2022-06-24 16:38:48 +03:00
/* hanxin.c - Han Xin Code */
/*
2016-04-07 19:13:43 +03:00
libzint - the open source barcode library
2024-02-06 16:01:35 +03:00
Copyright ( C ) 2009 - 2024 Robin Stuart < rstuart114 @ gmail . com >
2016-04-07 19:13:43 +03:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE .
*/
2022-06-24 16:38:48 +03:00
/* SPDX-License-Identifier: BSD-3-Clause */
2016-04-07 19:13:43 +03:00
2022-04-10 13:12:18 +03:00
/* This code attempts to implement Han Xin Code according to ISO/IEC 20830:2021
* ( previously ISO / IEC 20830 ( draft 2019 - 10 - 10 ) and AIMD - 015 : 2010 ( Rev 0.8 ) ) */
2016-04-07 19:13:43 +03:00
2022-09-14 00:08:08 +03:00
# include <assert.h>
2016-04-07 19:13:43 +03:00
# include <stdio.h>
# include "common.h"
# include "reedsol.h"
# include "hanxin.h"
2021-01-11 21:11:41 +03:00
# include "eci.h"
2016-04-07 19:13:43 +03:00
2016-04-09 19:01:21 +03:00
/* Find which submode to use for a text character */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_getsubmode ( const unsigned int input ) {
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_isdigit ( input ) ) {
2020-11-27 15:54:44 +03:00
return 1 ;
2016-04-09 19:01:21 +03:00
}
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_isupper ( input ) ) {
2020-11-27 15:54:44 +03:00
return 1 ;
2016-04-09 19:01:21 +03:00
}
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_islower ( input ) ) {
2020-11-27 15:54:44 +03:00
return 1 ;
2016-04-09 19:01:21 +03:00
}
2017-10-23 22:37:52 +03:00
2020-11-27 15:54:44 +03:00
return 2 ;
2016-04-09 19:01:21 +03:00
}
2019-12-08 19:15:34 +03:00
/* Return length of terminator for encoding mode */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_terminator_length ( const char mode ) {
2019-12-08 19:15:34 +03:00
int result = 0 ;
switch ( mode ) {
case ' n ' :
result = 10 ;
break ;
case ' t ' :
result = 6 ;
break ;
case ' 1 ' :
case ' 2 ' :
result = 12 ;
break ;
case ' d ' :
result = 15 ;
break ;
}
return result ;
}
/* Calculate the length of the binary string */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_calc_binlen ( const char mode [ ] , const unsigned int ddata [ ] , const int length , const int eci ) {
2020-11-27 15:54:44 +03:00
int i ;
2019-12-08 19:15:34 +03:00
char lastmode = ' \0 ' ;
2016-04-08 00:30:37 +03:00
int est_binlen = 0 ;
2016-04-09 19:01:21 +03:00
int submode = 1 ;
2019-12-08 19:15:34 +03:00
int numeric_run = 0 ;
2017-10-23 22:37:52 +03:00
2019-10-06 19:39:54 +03:00
if ( eci ! = 0 ) {
2019-12-08 19:15:34 +03:00
est_binlen + = 4 ;
if ( eci < = 127 ) {
est_binlen + = 8 ;
2020-11-27 15:54:44 +03:00
} else if ( eci < = 16383 ) {
2019-12-08 19:15:34 +03:00
est_binlen + = 16 ;
} else {
est_binlen + = 24 ;
}
2016-08-16 14:43:41 +03:00
}
2017-10-23 22:37:52 +03:00
2016-05-02 00:10:50 +03:00
i = 0 ;
do {
2019-12-08 19:15:34 +03:00
if ( mode [ i ] ! = lastmode ) {
if ( i > 0 ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
est_binlen + = hx_terminator_length ( lastmode ) ;
2019-12-08 19:15:34 +03:00
}
/* GB 4-byte has indicator for each character (and no terminator) so not included here */
/* Region1/Region2 have special terminator to go directly into each other's mode so not included here */
if ( mode [ i ] ! = ' f ' | | ( ( mode [ i ] = = ' 1 ' & & lastmode = = ' 2 ' ) | | ( mode [ i ] = = ' 2 ' & & lastmode = = ' 1 ' ) ) ) {
est_binlen + = 4 ;
}
if ( mode [ i ] = = ' b ' ) { /* Byte mode has byte count (and no terminator) */
est_binlen + = 13 ;
}
lastmode = mode [ i ] ;
submode = 1 ;
numeric_run = 0 ;
}
2016-04-08 00:30:37 +03:00
switch ( mode [ i ] ) {
case ' n ' :
2019-12-08 19:15:34 +03:00
if ( numeric_run % 3 = = 0 ) {
est_binlen + = 10 ;
2016-04-08 00:30:37 +03:00
}
2019-12-08 19:15:34 +03:00
numeric_run + + ;
2016-04-08 00:30:37 +03:00
break ;
case ' t ' :
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_getsubmode ( ddata [ i ] ) ! = submode ) {
2016-04-09 19:01:21 +03:00
est_binlen + = 6 ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
submode = hx_getsubmode ( ddata [ i ] ) ;
2016-04-08 00:30:37 +03:00
}
est_binlen + = 6 ;
2016-04-10 22:36:57 +03:00
break ;
2016-04-08 00:30:37 +03:00
case ' b ' :
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
est_binlen + = ddata [ i ] > 0xFF ? 16 : 8 ;
2016-04-10 22:36:57 +03:00
break ;
2016-05-02 00:10:50 +03:00
case ' 1 ' :
case ' 2 ' :
est_binlen + = 12 ;
break ;
case ' d ' :
est_binlen + = 15 ;
break ;
case ' f ' :
2019-12-08 19:15:34 +03:00
est_binlen + = 25 ;
2016-05-02 00:10:50 +03:00
i + + ;
break ;
2016-04-08 00:30:37 +03:00
}
2016-05-02 00:10:50 +03:00
i + + ;
} while ( i < length ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
est_binlen + = hx_terminator_length ( lastmode ) ;
2019-12-08 19:15:34 +03:00
2016-04-08 00:30:37 +03:00
return est_binlen ;
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
/* Call `hx_calc_binlen()` for each segment */
static int hx_calc_binlen_segs ( const char mode [ ] , const unsigned int ddata [ ] , const struct zint_seg segs [ ] ,
const int seg_count ) {
int i ;
int count = 0 ;
const unsigned int * dd = ddata ;
const char * m = mode ;
for ( i = 0 ; i < seg_count ; i + + ) {
count + = hx_calc_binlen ( m , dd , segs [ i ] . length , segs [ i ] . eci ) ;
m + = segs [ i ] . length ;
dd + = segs [ i ] . length ;
}
return count ;
}
static int hx_isRegion1 ( const unsigned int glyph ) {
2020-11-27 15:54:44 +03:00
unsigned int byte ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
byte = glyph > > 8 ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ( byte > = 0xb0 ) & & ( byte < = 0xd7 ) ) {
byte = glyph & 0xff ;
if ( ( byte > = 0xa1 ) & & ( byte < = 0xfe ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
2020-11-27 15:54:44 +03:00
} else if ( ( byte > = 0xa1 ) & & ( byte < = 0xa3 ) ) {
byte = glyph & 0xff ;
if ( ( byte > = 0xa1 ) & & ( byte < = 0xfe ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
2020-11-27 15:54:44 +03:00
} else if ( ( glyph > = 0xa8a1 ) & & ( glyph < = 0xa8c0 ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
return 0 ;
2016-05-02 00:10:50 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_isRegion2 ( const unsigned int glyph ) {
2020-11-27 15:54:44 +03:00
unsigned int byte ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
byte = glyph > > 8 ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ( byte > = 0xd8 ) & & ( byte < = 0xf7 ) ) {
byte = glyph & 0xff ;
if ( ( byte > = 0xa1 ) & & ( byte < = 0xfe ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
return 0 ;
2016-05-02 00:10:50 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_isDoubleByte ( const unsigned int glyph ) {
2020-11-27 15:54:44 +03:00
unsigned int byte ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
byte = glyph > > 8 ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ( byte > = 0x81 ) & & ( byte < = 0xfe ) ) {
byte = glyph & 0xff ;
if ( ( byte > = 0x40 ) & & ( byte < = 0x7e ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
2020-11-27 15:54:44 +03:00
if ( ( byte > = 0x80 ) & & ( byte < = 0xfe ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
return 0 ;
2016-05-02 00:10:50 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_isFourByte ( const unsigned int glyph , const unsigned int glyph2 ) {
2020-11-27 15:54:44 +03:00
unsigned int byte ;
byte = glyph > > 8 ;
if ( ( byte > = 0x81 ) & & ( byte < = 0xfe ) ) {
byte = glyph & 0xff ;
if ( ( byte > = 0x30 ) & & ( byte < = 0x39 ) ) {
byte = glyph2 > > 8 ;
if ( ( byte > = 0x81 ) & & ( byte < = 0xfe ) ) {
byte = glyph2 & 0xff ;
if ( ( byte > = 0x30 ) & & ( byte < = 0x39 ) ) {
return 1 ;
2016-05-02 00:10:50 +03:00
}
}
}
}
2017-10-23 22:37:52 +03:00
2020-11-27 15:54:44 +03:00
return 0 ;
2016-05-02 00:10:50 +03:00
}
2016-04-08 00:30:37 +03:00
/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_lookup_text1 ( const unsigned int input ) {
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_isdigit ( input ) ) {
2020-11-27 15:54:44 +03:00
return input - ' 0 ' ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_isupper ( input ) ) {
2020-11-27 15:54:44 +03:00
return input - ' A ' + 10 ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2022-06-24 16:38:48 +03:00
if ( z_islower ( input ) ) {
2020-11-27 15:54:44 +03:00
return input - ' a ' + 36 ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2020-11-27 15:54:44 +03:00
return - 1 ;
2016-04-08 00:30:37 +03:00
}
/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_lookup_text2 ( const unsigned int input ) {
2017-10-23 22:37:52 +03:00
2019-12-08 19:15:34 +03:00
if ( input < = 27 ) {
2020-11-27 15:54:44 +03:00
return input ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2016-04-08 00:30:37 +03:00
if ( ( input > = ' ' ) & & ( input < = ' / ' ) ) {
2020-11-27 15:54:44 +03:00
return input - ' ' + 28 ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2019-12-08 19:15:34 +03:00
if ( ( input > = ' : ' ) & & ( input < = ' @ ' ) ) {
2020-11-27 15:54:44 +03:00
return input - ' : ' + 44 ;
2019-12-08 19:15:34 +03:00
}
2016-04-08 00:30:37 +03:00
if ( ( input > = ' [ ' ) & & ( input < = 96 ) ) {
2020-11-27 15:54:44 +03:00
return input - ' [ ' + 51 ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2016-04-08 00:30:37 +03:00
if ( ( input > = ' { ' ) & & ( input < = 127 ) ) {
2020-11-27 15:54:44 +03:00
return input - ' { ' + 57 ;
2016-04-08 00:30:37 +03:00
}
2017-10-23 22:37:52 +03:00
2020-11-27 15:54:44 +03:00
return - 1 ;
2016-04-08 00:30:37 +03:00
}
2019-12-08 19:15:34 +03:00
/* hx_define_mode() stuff */
/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
# define HX_MULT 6
2020-11-27 15:54:44 +03:00
/* Whether in numeric or not. If in numeric, *p_end is set to position after numeric,
* and * p_cost is set to per - numeric cost */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_in_numeric ( const unsigned int ddata [ ] , const int length , const int in_posn ,
2020-11-27 15:54:44 +03:00
unsigned int * p_end , unsigned int * p_cost ) {
int i , digit_cnt ;
2019-12-08 19:15:34 +03:00
2020-11-27 15:54:44 +03:00
if ( in_posn < ( int ) * p_end ) {
2019-12-08 19:15:34 +03:00
return 1 ;
}
/* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times HX_MULT) */
2023-12-09 13:07:11 +03:00
for ( i = in_posn ; i < length & & i < in_posn + 3 & & z_isdigit ( ddata [ i ] ) ; i + + ) ;
2019-12-08 19:15:34 +03:00
2020-11-27 15:54:44 +03:00
digit_cnt = i - in_posn ;
2019-12-08 23:22:10 +03:00
if ( digit_cnt = = 0 ) {
2019-12-08 19:15:34 +03:00
* p_end = 0 ;
return 0 ;
}
* p_end = i ;
2021-06-19 15:11:23 +03:00
* p_cost = digit_cnt = = 1
? 60 /* 10 * HX_MULT */ : digit_cnt = = 2 ? 30 /* (10 / 2) * HX_MULT */ : 20 /* (10 / 3) * HX_MULT */ ;
2019-12-08 19:15:34 +03:00
return 1 ;
}
2020-11-27 15:54:44 +03:00
/* Whether in four-byte or not. If in four-byte, *p_fourbyte is set to position after four-byte,
* and * p_fourbyte_cost is set to per - position cost */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static int hx_in_fourbyte ( const unsigned int ddata [ ] , const int length , const int in_posn ,
2020-11-27 15:54:44 +03:00
unsigned int * p_end , unsigned int * p_cost ) {
if ( in_posn < ( int ) * p_end ) {
2019-12-08 19:15:34 +03:00
return 1 ;
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( in_posn = = length - 1 | | ! hx_isFourByte ( ddata [ in_posn ] , ddata [ in_posn + 1 ] ) ) {
2019-12-08 19:15:34 +03:00
* p_end = 0 ;
return 0 ;
}
2020-11-27 15:54:44 +03:00
* p_end = in_posn + 2 ;
2019-12-08 19:15:34 +03:00
* p_cost = 75 ; /* ((4 + 21) / 2) * HX_MULT */
return 1 ;
}
/* Indexes into mode_types array */
# define HX_N 0 /* Numeric */
# define HX_T 1 /* Text */
# define HX_B 2 /* Binary */
# define HX_1 3 /* Common Chinese Region One */
# define HX_2 4 /* Common Chinese Region Two */
# define HX_D 5 /* GB 18030 2-byte Region */
# define HX_F 6 /* GB 18030 4-byte Region */
/* Note Unicode, GS1 and URI modes not implemented */
# define HX_NUM_MODES 7
2020-11-27 15:54:44 +03:00
/* Calculate optimized encoding modes. Adapted from Project Nayuki */
/* Copyright (c) Project Nayuki. (MIT License) See qr.c for detailed notice */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static void hx_define_mode ( char * mode , const unsigned int ddata [ ] , const int length , const int debug_print ) {
2020-11-27 15:54:44 +03:00
/* Must be in same order as HX_N etc */
static const char mode_types [ ] = { ' n ' , ' t ' , ' b ' , ' 1 ' , ' 2 ' , ' d ' , ' f ' , ' \0 ' } ;
/* Initial mode costs */
2021-10-31 00:00:31 +03:00
static const unsigned int head_costs [ HX_NUM_MODES ] = {
2019-12-08 19:15:34 +03:00
/* N T B 1 2 D F */
4 * HX_MULT , 4 * HX_MULT , ( 4 + 13 ) * HX_MULT , 4 * HX_MULT , 4 * HX_MULT , 4 * HX_MULT , 0
} ;
2020-11-27 15:54:44 +03:00
/* Cost of switching modes from k to j */
2019-12-19 03:37:55 +03:00
static const unsigned int switch_costs [ HX_NUM_MODES ] [ HX_NUM_MODES ] = {
2019-12-08 19:15:34 +03:00
/* N T B 1 2 D F */
/*N*/ { 0 , ( 10 + 4 ) * HX_MULT , ( 10 + 4 + 13 ) * HX_MULT , ( 10 + 4 ) * HX_MULT , ( 10 + 4 ) * HX_MULT , ( 10 + 4 ) * HX_MULT , 10 * HX_MULT } ,
/*T*/ { ( 6 + 4 ) * HX_MULT , 0 , ( 6 + 4 + 13 ) * HX_MULT , ( 6 + 4 ) * HX_MULT , ( 6 + 4 ) * HX_MULT , ( 6 + 4 ) * HX_MULT , 6 * HX_MULT } ,
/*B*/ { 4 * HX_MULT , 4 * HX_MULT , 0 , 4 * HX_MULT , 4 * HX_MULT , 4 * HX_MULT , 0 } ,
/*1*/ { ( 12 + 4 ) * HX_MULT , ( 12 + 4 ) * HX_MULT , ( 12 + 4 + 13 ) * HX_MULT , 0 , 12 * HX_MULT , ( 12 + 4 ) * HX_MULT , 12 * HX_MULT } ,
/*2*/ { ( 12 + 4 ) * HX_MULT , ( 12 + 4 ) * HX_MULT , ( 12 + 4 + 13 ) * HX_MULT , 12 * HX_MULT , 0 , ( 12 + 4 ) * HX_MULT , 12 * HX_MULT } ,
/*D*/ { ( 15 + 4 ) * HX_MULT , ( 15 + 4 ) * HX_MULT , ( 15 + 4 + 13 ) * HX_MULT , ( 15 + 4 ) * HX_MULT , ( 15 + 4 ) * HX_MULT , 0 , 15 * HX_MULT } ,
/*F*/ { 4 * HX_MULT , 4 * HX_MULT , ( 4 + 13 ) * HX_MULT , 4 * HX_MULT , 4 * HX_MULT , 4 * HX_MULT , 0 } ,
} ;
2020-11-27 15:54:44 +03:00
/* Final end-of-data costs */
2019-12-19 03:37:55 +03:00
static const unsigned int eod_costs [ HX_NUM_MODES ] = {
2019-12-08 19:15:34 +03:00
/* N T B 1 2 D F */
10 * HX_MULT , 6 * HX_MULT , 0 , 12 * HX_MULT , 12 * HX_MULT , 15 * HX_MULT , 0
} ;
2020-11-27 15:54:44 +03:00
unsigned int numeric_end = 0 , numeric_cost = 0 , text_submode = 1 , fourbyte_end = 0 , fourbyte_cost = 0 ; /* State */
2019-12-08 19:15:34 +03:00
int text1 , text2 ;
2024-02-06 16:01:35 +03:00
int i , j , k ;
2020-11-27 15:54:44 +03:00
unsigned int min_cost ;
char cur_mode ;
unsigned int prev_costs [ HX_NUM_MODES ] ;
unsigned int cur_costs [ HX_NUM_MODES ] ;
2024-02-06 16:01:35 +03:00
char ( * char_modes ) [ HX_NUM_MODES ] = ( char ( * ) [ HX_NUM_MODES ] ) z_alloca ( HX_NUM_MODES * length ) ;
2020-11-27 15:54:44 +03:00
2024-02-06 16:01:35 +03:00
/* char_modes[i][j] represents the mode to encode the code point at index i such that the final segment
ends in mode_types [ j ] and the total number of bits is minimized over all possible choices */
memset ( char_modes , 0 , HX_NUM_MODES * length ) ;
2019-12-08 19:15:34 +03:00
2020-11-27 15:54:44 +03:00
/* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
* bits needed to encode the entire string prefix of length i , and end in mode_types [ j ] */
memcpy ( prev_costs , head_costs , HX_NUM_MODES * sizeof ( unsigned int ) ) ;
2019-12-08 19:15:34 +03:00
2020-11-27 15:54:44 +03:00
/* Calculate costs using dynamic programming */
2024-02-06 16:01:35 +03:00
for ( i = 0 ; i < length ; i + + ) {
2020-11-27 15:54:44 +03:00
memset ( cur_costs , 0 , HX_NUM_MODES * sizeof ( unsigned int ) ) ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_in_numeric ( ddata , length , i , & numeric_end , & numeric_cost ) ) {
2020-11-27 15:54:44 +03:00
cur_costs [ HX_N ] = prev_costs [ HX_N ] + numeric_cost ;
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_N ] = ' n ' ;
2020-11-27 18:24:37 +03:00
text1 = 1 ;
text2 = 0 ;
} else {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
text1 = hx_lookup_text1 ( ddata [ i ] ) ! = - 1 ;
text2 = hx_lookup_text2 ( ddata [ i ] ) ! = - 1 ;
2020-11-27 15:54:44 +03:00
}
if ( text1 | | text2 ) {
if ( ( text_submode = = 1 & & text2 ) | | ( text_submode = = 2 & & text1 ) ) {
cur_costs [ HX_T ] = prev_costs [ HX_T ] + 72 ; /* (6 + 6) * HX_MULT */
text_submode = text2 ? 2 : 1 ;
} else {
cur_costs [ HX_T ] = prev_costs [ HX_T ] + 36 ; /* 6 * HX_MULT */
}
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_T ] = ' t ' ;
2019-12-08 19:15:34 +03:00
} else {
2020-11-27 15:54:44 +03:00
text_submode = 1 ;
2019-12-08 19:15:34 +03:00
}
2020-11-27 15:54:44 +03:00
/* Binary mode can encode anything */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
cur_costs [ HX_B ] = prev_costs [ HX_B ] + ( ddata [ i ] > 0xFF ? 96 : 48 ) ; /* (16 : 8) * HX_MULT */
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_B ] = ' b ' ;
2019-12-08 19:15:34 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_in_fourbyte ( ddata , length , i , & fourbyte_end , & fourbyte_cost ) ) {
2020-11-27 15:54:44 +03:00
cur_costs [ HX_F ] = prev_costs [ HX_F ] + fourbyte_cost ;
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_F ] = ' f ' ;
2020-11-27 18:24:37 +03:00
} else {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_isDoubleByte ( ddata [ i ] ) ) {
2020-11-27 18:24:37 +03:00
cur_costs [ HX_D ] = prev_costs [ HX_D ] + 90 ; /* 15 * HX_MULT */
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_D ] = ' d ' ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_isRegion1 ( ddata [ i ] ) ) { /* Subset */
2020-11-27 18:24:37 +03:00
cur_costs [ HX_1 ] = prev_costs [ HX_1 ] + 72 ; /* 12 * HX_MULT */
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_1 ] = ' 1 ' ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
} else if ( hx_isRegion2 ( ddata [ i ] ) ) { /* Subset */
2020-11-27 18:24:37 +03:00
cur_costs [ HX_2 ] = prev_costs [ HX_2 ] + 72 ; /* 12 * HX_MULT */
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ HX_2 ] = ' 2 ' ;
2020-11-27 18:24:37 +03:00
}
}
2020-11-27 15:54:44 +03:00
}
if ( i = = length - 1 ) { /* Add end of data costs if last character */
for ( j = 0 ; j < HX_NUM_MODES ; j + + ) {
2024-02-06 16:01:35 +03:00
if ( char_modes [ i ] [ j ] ) {
2020-11-27 15:54:44 +03:00
cur_costs [ j ] + = eod_costs [ j ] ;
}
}
}
/* Start new segment at the end to switch modes */
for ( j = 0 ; j < HX_NUM_MODES ; j + + ) { /* To mode */
for ( k = 0 ; k < HX_NUM_MODES ; k + + ) { /* From mode */
2024-02-06 16:01:35 +03:00
if ( j ! = k & & char_modes [ i ] [ k ] ) {
2021-10-31 00:00:31 +03:00
const unsigned int new_cost = cur_costs [ k ] + switch_costs [ k ] [ j ] ;
2024-02-06 16:01:35 +03:00
if ( ! char_modes [ i ] [ j ] | | new_cost < cur_costs [ j ] ) {
2020-11-27 15:54:44 +03:00
cur_costs [ j ] = new_cost ;
2024-02-06 16:01:35 +03:00
char_modes [ i ] [ j ] = mode_types [ k ] ;
2020-11-27 15:54:44 +03:00
}
}
}
}
memcpy ( prev_costs , cur_costs , HX_NUM_MODES * sizeof ( unsigned int ) ) ;
2019-12-08 19:15:34 +03:00
}
2020-11-27 15:54:44 +03:00
/* Find optimal ending mode */
min_cost = prev_costs [ 0 ] ;
cur_mode = mode_types [ 0 ] ;
for ( i = 1 ; i < HX_NUM_MODES ; i + + ) {
if ( prev_costs [ i ] < min_cost ) {
min_cost = prev_costs [ i ] ;
cur_mode = mode_types [ i ] ;
}
2019-12-08 19:15:34 +03:00
}
2020-11-27 15:54:44 +03:00
/* Get optimal mode for each code point by tracing backwards */
2024-02-06 16:01:35 +03:00
for ( i = length - 1 ; i > = 0 ; i - - ) {
2021-10-21 01:05:30 +03:00
j = posn ( mode_types , cur_mode ) ;
2024-02-06 16:01:35 +03:00
cur_mode = char_modes [ i ] [ j ] ;
2020-11-27 15:54:44 +03:00
mode [ i ] = cur_mode ;
}
2019-12-08 19:15:34 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2020-11-27 15:54:44 +03:00
printf ( " Mode: %.*s \n " , length , mode ) ;
}
2019-12-08 19:15:34 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
/* Call `hx_define_mode()` for each segment */
static void hx_define_mode_segs ( char mode [ ] , const unsigned int ddata [ ] , const struct zint_seg segs [ ] ,
const int seg_count , const int debug_print ) {
int i ;
const unsigned int * dd = ddata ;
char * m = mode ;
for ( i = 0 ; i < seg_count ; i + + ) {
hx_define_mode ( m , dd , segs [ i ] . length , debug_print ) ;
m + = segs [ i ] . length ;
dd + = segs [ i ] . length ;
}
}
2016-04-08 00:30:37 +03:00
/* Convert input data to binary stream */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static void hx_calculate_binary ( char binary [ ] , const char mode [ ] , const unsigned int ddata [ ] , const int length ,
const int eci , int * p_bp , const int debug_print ) {
2020-11-27 15:54:44 +03:00
int position = 0 ;
2017-05-14 10:15:08 +03:00
int i , count , encoding_value ;
2016-05-02 00:10:50 +03:00
int first_byte , second_byte ;
int third_byte , fourth_byte ;
int glyph ;
2016-08-16 14:43:41 +03:00
int submode ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
int bp = * p_bp ;
2016-09-06 00:06:50 +03:00
2019-10-06 19:39:54 +03:00
if ( eci ! = 0 ) {
2017-06-18 15:00:22 +03:00
/* Encoding ECI assignment number, according to Table 5 */
2022-07-14 18:01:30 +03:00
bp = bin_append_posn ( 8 , 4 , binary , bp ) ; /* ECI */
2017-06-18 15:00:22 +03:00
if ( eci < = 127 ) {
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( eci , 8 , binary , bp ) ;
} else if ( eci < = 16383 ) {
bp = bin_append_posn ( 2 , 2 , binary , bp ) ;
bp = bin_append_posn ( eci , 14 , binary , bp ) ;
} else {
bp = bin_append_posn ( 6 , 3 , binary , bp ) ;
bp = bin_append_posn ( eci , 21 , binary , bp ) ;
2017-06-18 15:00:22 +03:00
}
2016-08-16 14:43:41 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
do {
2017-09-10 18:03:09 +03:00
int block_length = 0 ;
2019-12-08 19:15:34 +03:00
int double_byte = 0 ;
2016-04-08 00:30:37 +03:00
do {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( mode [ position ] = = ' b ' & & ddata [ position + block_length ] > 0xFF ) {
2019-12-08 19:15:34 +03:00
double_byte + + ;
}
2016-04-08 00:30:37 +03:00
block_length + + ;
2019-12-08 19:15:34 +03:00
} while ( position + block_length < length & & mode [ position + block_length ] = = mode [ position ] ) ;
2016-09-06 00:06:50 +03:00
switch ( mode [ position ] ) {
2016-04-08 00:30:37 +03:00
case ' n ' :
/* Numeric mode */
/* Mode indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 1 , 4 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Numeric (N%d): " , block_length ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2019-11-27 19:16:14 +03:00
count = 0 ; /* Suppress gcc -Wmaybe-uninitialized */
2016-04-08 00:30:37 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
while ( i < block_length ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int first = ctoi ( ( const char ) ddata [ position + i ] ) ;
2016-04-08 00:30:37 +03:00
count = 1 ;
encoding_value = first ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
if ( i + 1 < block_length & & mode [ position + i + 1 ] = = ' n ' ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int second = ctoi ( ( const char ) ddata [ position + i + 1 ] ) ;
2016-04-08 00:30:37 +03:00
count = 2 ;
encoding_value = ( encoding_value * 10 ) + second ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
if ( i + 2 < block_length & & mode [ position + i + 2 ] = = ' n ' ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int third = ctoi ( ( const char ) ddata [ position + i + 2 ] ) ;
2016-04-08 00:30:37 +03:00
count = 3 ;
encoding_value = ( encoding_value * 10 ) + third ;
}
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( encoding_value , 10 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " 0x%3x(%d) " , encoding_value , encoding_value ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
i + = count ;
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
/* Mode terminator depends on number of characters in last group (Table 2) */
switch ( count ) {
case 1 :
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 1021 , 10 , binary , bp ) ;
2016-04-08 00:30:37 +03:00
break ;
case 2 :
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 1022 , 10 , binary , bp ) ;
2016-04-08 00:30:37 +03:00
break ;
case 3 :
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 1023 , 10 , binary , bp ) ;
2016-04-08 00:30:37 +03:00
break ;
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2016-04-08 00:30:37 +03:00
printf ( " (TERM %d) \n " , count ) ;
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
break ;
case ' t ' :
/* Text mode */
2019-12-08 19:15:34 +03:00
/* Mode indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 2 , 4 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Text (T%d): " , block_length ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2016-07-04 13:08:08 +03:00
submode = 1 ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
while ( i < block_length ) {
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( hx_getsubmode ( ddata [ i + position ] ) ! = submode ) {
2016-04-08 00:30:37 +03:00
/* Change submode */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 62 , 6 , binary , bp ) ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
submode = hx_getsubmode ( ddata [ i + position ] ) ;
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
fputs ( " SWITCH " , stdout ) ;
2016-04-08 00:30:37 +03:00
}
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
if ( submode = = 1 ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
encoding_value = hx_lookup_text1 ( ddata [ i + position ] ) ;
2016-04-08 00:30:37 +03:00
} else {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
encoding_value = hx_lookup_text2 ( ddata [ i + position ] ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( encoding_value , 6 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " %.2x[ASC %.2x] " , encoding_value , ddata [ i + position ] ) ;
2016-04-08 00:30:37 +03:00
}
i + + ;
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
/* Terminator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 63 , 6 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
fputs ( " \n " , stdout ) ;
2016-04-08 00:30:37 +03:00
}
break ;
case ' b ' :
/* Binary Mode */
/* Mode indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 3 , 4 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
/* Count indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( block_length + double_byte , 13 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Binary Mode (B%d): " , block_length + double_byte ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
while ( i < block_length ) {
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
/* 8-bit bytes with no conversion */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
bp = bin_append_posn ( ddata [ i + position ] , ddata [ i + position ] > 0xFF ? 16 : 8 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
printf ( " %02x " , ( int ) ddata [ i + position ] ) ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
i + + ;
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
fputs ( " \n " , stdout ) ;
2016-04-08 00:30:37 +03:00
}
break ;
2016-05-02 00:10:50 +03:00
case ' 1 ' :
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
/* Region One encoding */
2016-05-02 00:10:50 +03:00
/* Mode indicator */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( position = = 0 | | mode [ position - 1 ] ! = ' 2 ' ) { /* Unless previous mode Region Two */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 4 , 4 , binary , bp ) ;
2019-12-08 19:15:34 +03:00
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Region One%s H(1)%d: " ,
position = = 0 | | mode [ position - 1 ] ! = ' 2 ' ? " " : " (NO indicator) " , block_length ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
while ( i < block_length ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
first_byte = ( ddata [ i + position ] & 0xff00 ) > > 8 ;
second_byte = ddata [ i + position ] & 0xff ;
2016-05-02 00:10:50 +03:00
/* Subset 1 */
glyph = ( 0x5e * ( first_byte - 0xb0 ) ) + ( second_byte - 0xa1 ) ;
/* Subset 2 */
if ( ( first_byte > = 0xa1 ) & & ( first_byte < = 0xa3 ) ) {
if ( ( second_byte > = 0xa1 ) & & ( second_byte < = 0xfe ) ) {
2019-11-17 17:56:43 +03:00
glyph = ( 0x5e * ( first_byte - 0xa1 ) ) + ( second_byte - 0xa1 ) + 0xeb0 ;
2016-05-02 00:10:50 +03:00
}
}
/* Subset 3 */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( ( ddata [ i + position ] > = 0xa8a1 ) & & ( ddata [ i + position ] < = 0xa8c0 ) ) {
2016-05-02 00:10:50 +03:00
glyph = ( second_byte - 0xa1 ) + 0xfca ;
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " %.3x[GB %.4x] " , glyph , ddata [ i + position ] ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( glyph , 12 , binary , bp ) ;
2016-05-02 00:10:50 +03:00
i + + ;
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
/* Terminator */
2021-06-19 15:11:23 +03:00
bp = bin_append_posn ( position + block_length = = length | | mode [ position + block_length ] ! = ' 2 '
? 4095 : 4094 , 12 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " (TERM %x) \n " , position + block_length = = length | | mode [ position + block_length ] ! = ' 2 '
2021-06-19 15:11:23 +03:00
? 4095 : 4094 ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
break ;
case ' 2 ' :
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
/* Region Two encoding */
2016-05-02 00:10:50 +03:00
/* Mode indicator */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( position = = 0 | | mode [ position - 1 ] ! = ' 1 ' ) { /* Unless previous mode Region One */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 5 , 4 , binary , bp ) ;
2019-12-08 19:15:34 +03:00
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Region Two%s H(2)%d: " ,
position = = 0 | | mode [ position - 1 ] ! = ' 1 ' ? " " : " (NO indicator) " , block_length ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
while ( i < block_length ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
first_byte = ( ddata [ i + position ] & 0xff00 ) > > 8 ;
second_byte = ddata [ i + position ] & 0xff ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
glyph = ( 0x5e * ( first_byte - 0xd8 ) ) + ( second_byte - 0xa1 ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " %.3x[GB %.4x] " , glyph , ddata [ i + position ] ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( glyph , 12 , binary , bp ) ;
2016-05-02 00:10:50 +03:00
i + + ;
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
/* Terminator */
2021-06-19 15:11:23 +03:00
bp = bin_append_posn ( position + block_length = = length | | mode [ position + block_length ] ! = ' 1 '
? 4095 : 4094 , 12 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " (TERM %x) \n " , position + block_length = = length | | mode [ position + block_length ] ! = ' 1 '
2021-06-19 15:11:23 +03:00
? 4095 : 4094 ) ;
2016-09-06 00:06:50 +03:00
}
2020-11-27 15:54:44 +03:00
2016-05-02 00:10:50 +03:00
break ;
case ' d ' :
/* Double byte encoding */
/* Mode indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 6 , 4 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Double byte (H(d)%d): " , block_length ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
while ( i < block_length ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
first_byte = ( ddata [ i + position ] & 0xff00 ) > > 8 ;
second_byte = ddata [ i + position ] & 0xff ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
if ( second_byte < = 0x7e ) {
glyph = ( 0xbe * ( first_byte - 0x81 ) ) + ( second_byte - 0x40 ) ;
} else {
glyph = ( 0xbe * ( first_byte - 0x81 ) ) + ( second_byte - 0x41 ) ;
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2019-11-17 17:56:43 +03:00
printf ( " %.4x " , glyph ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( glyph , 15 , binary , bp ) ;
2016-05-02 00:10:50 +03:00
i + + ;
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
/* Terminator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 32767 , 15 , binary , bp ) ;
2016-10-27 14:35:53 +03:00
/* Terminator sequence of length 12 is a mistake
- confirmed by Wang Yi */
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
fputc ( ' \n ' , stdout ) ;
2016-09-06 00:06:50 +03:00
}
2016-05-02 00:10:50 +03:00
break ;
case ' f ' :
/* Four-byte encoding */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Four byte (H(f)%d): " , block_length ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
i = 0 ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
while ( i < block_length ) {
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
/* Mode indicator */
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( 7 , 4 , binary , bp ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
first_byte = ( ddata [ i + position ] & 0xff00 ) > > 8 ;
second_byte = ddata [ i + position ] & 0xff ;
third_byte = ( ddata [ i + position + 1 ] & 0xff00 ) > > 8 ;
fourth_byte = ddata [ i + position + 1 ] & 0xff ;
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
glyph = ( 0x3138 * ( first_byte - 0x81 ) ) + ( 0x04ec * ( second_byte - 0x30 ) ) +
( 0x0a * ( third_byte - 0x81 ) ) + ( fourth_byte - 0x30 ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " %d " , glyph ) ;
2016-05-02 00:10:50 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
bp = bin_append_posn ( glyph , 21 , binary , bp ) ;
2016-05-02 00:10:50 +03:00
i + = 2 ;
}
2016-09-06 00:06:50 +03:00
2016-05-02 00:10:50 +03:00
/* No terminator */
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
fputc ( ' \n ' , stdout ) ;
2016-05-02 00:10:50 +03:00
}
break ;
2016-04-08 00:30:37 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
position + = block_length ;
2016-09-06 00:06:50 +03:00
2016-04-08 00:30:37 +03:00
} while ( position < length ) ;
2020-11-27 15:54:44 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) printf ( " Binary (%d): %.*s \n " , bp , bp , binary ) ;
2020-11-27 15:54:44 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
* p_bp = bp ;
}
/* Call `hx_calculate_binary()` for each segment */
static void hx_calculate_binary_segs ( char binary [ ] , const char mode [ ] , const unsigned int ddata [ ] ,
const struct zint_seg segs [ ] , const int seg_count , int * p_bin_len , const int debug_print ) {
int i ;
const unsigned int * dd = ddata ;
const char * m = mode ;
int bp = 0 ;
for ( i = 0 ; i < seg_count ; i + + ) {
hx_calculate_binary ( binary , m , dd , segs [ i ] . length , segs [ i ] . eci , & bp , debug_print ) ;
m + = segs [ i ] . length ;
dd + = segs [ i ] . length ;
}
2020-11-27 15:54:44 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
* p_bin_len = bp ;
2016-04-08 00:30:37 +03:00
}
2016-04-09 19:01:21 +03:00
/* Finder pattern for top left of symbol */
2020-11-27 15:54:44 +03:00
static void hx_place_finder_top_left ( unsigned char * grid , const int size ) {
2016-04-09 19:01:21 +03:00
int xp , yp ;
int x = 0 , y = 0 ;
2017-08-07 10:37:02 +03:00
char finder [ ] = { 0x7F , 0x40 , 0x5F , 0x50 , 0x57 , 0x57 , 0x57 } ;
2017-10-23 22:37:52 +03:00
2016-04-09 19:01:21 +03:00
for ( xp = 0 ; xp < 7 ; xp + + ) {
for ( yp = 0 ; yp < 7 ; yp + + ) {
2017-08-07 10:37:02 +03:00
if ( finder [ yp ] & 0x40 > > xp ) {
2016-04-09 19:01:21 +03:00
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x11 ;
} else {
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x10 ;
}
}
}
}
/* Finder pattern for top right and bottom left of symbol */
2020-11-27 15:54:44 +03:00
static void hx_place_finder ( unsigned char * grid , const int size , const int x , const int y ) {
2016-04-09 19:01:21 +03:00
int xp , yp ;
2021-10-31 00:00:31 +03:00
static const char finder [ ] = { 0x7F , 0x01 , 0x7D , 0x05 , 0x75 , 0x75 , 0x75 } ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
for ( xp = 0 ; xp < 7 ; xp + + ) {
for ( yp = 0 ; yp < 7 ; yp + + ) {
2017-08-07 10:37:02 +03:00
if ( finder [ yp ] & 0x40 > > xp ) {
2016-04-09 19:01:21 +03:00
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x11 ;
} else {
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x10 ;
}
}
}
}
/* Finder pattern for bottom right of symbol */
2020-11-27 15:54:44 +03:00
static void hx_place_finder_bottom_right ( unsigned char * grid , const int size ) {
2016-04-09 19:01:21 +03:00
int xp , yp ;
2021-10-31 00:00:31 +03:00
const int x = size - 7 ;
const int y = x ;
static const char finder [ ] = { 0x75 , 0x75 , 0x75 , 0x05 , 0x7D , 0x01 , 0x7F } ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
for ( xp = 0 ; xp < 7 ; xp + + ) {
for ( yp = 0 ; yp < 7 ; yp + + ) {
2017-08-07 10:37:02 +03:00
if ( finder [ yp ] & 0x40 > > xp ) {
2016-04-09 19:01:21 +03:00
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x11 ;
} else {
grid [ ( ( yp + y ) * size ) + ( xp + x ) ] = 0x10 ;
}
}
}
}
/* Avoid plotting outside symbol or over finder patterns */
2020-11-27 15:54:44 +03:00
static void hx_safe_plot ( unsigned char * grid , const int size , const int x , const int y , const int value ) {
2016-04-09 19:01:21 +03:00
if ( ( x > = 0 ) & & ( x < size ) ) {
if ( ( y > = 0 ) & & ( y < size ) ) {
if ( grid [ ( y * size ) + x ] = = 0 ) {
grid [ ( y * size ) + x ] = value ;
}
}
}
}
/* Plot an alignment pattern around top and right of a module */
2021-06-19 15:11:23 +03:00
static void hx_plot_alignment ( unsigned char * grid , const int size , const int x , const int y , const int w ,
const int h ) {
2016-04-09 19:01:21 +03:00
int i ;
hx_safe_plot ( grid , size , x , y , 0x11 ) ;
hx_safe_plot ( grid , size , x - 1 , y + 1 , 0x10 ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
for ( i = 1 ; i < = w ; i + + ) {
/* Top */
hx_safe_plot ( grid , size , x - i , y , 0x11 ) ;
hx_safe_plot ( grid , size , x - i - 1 , y + 1 , 0x10 ) ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
for ( i = 1 ; i < h ; i + + ) {
/* Right */
hx_safe_plot ( grid , size , x , y + i , 0x11 ) ;
hx_safe_plot ( grid , size , x - 1 , y + i + 1 , 0x10 ) ;
}
}
2016-04-10 22:36:57 +03:00
/* Plot assistant alignment patterns */
2020-11-27 15:54:44 +03:00
static void hx_plot_assistant ( unsigned char * grid , const int size , const int x , const int y ) {
2016-04-09 19:01:21 +03:00
hx_safe_plot ( grid , size , x - 1 , y - 1 , 0x10 ) ;
hx_safe_plot ( grid , size , x , y - 1 , 0x10 ) ;
hx_safe_plot ( grid , size , x + 1 , y - 1 , 0x10 ) ;
hx_safe_plot ( grid , size , x - 1 , y , 0x10 ) ;
hx_safe_plot ( grid , size , x , y , 0x11 ) ;
hx_safe_plot ( grid , size , x + 1 , y , 0x10 ) ;
hx_safe_plot ( grid , size , x - 1 , y + 1 , 0x10 ) ;
hx_safe_plot ( grid , size , x , y + 1 , 0x10 ) ;
2016-09-06 00:06:50 +03:00
hx_safe_plot ( grid , size , x + 1 , y + 1 , 0x10 ) ;
2016-04-09 19:01:21 +03:00
}
/* Put static elements in the grid */
2020-11-27 15:54:44 +03:00
static void hx_setup_grid ( unsigned char * grid , const int size , const int version ) {
int i ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
memset ( grid , 0 , ( size_t ) size * size ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Add finder patterns */
hx_place_finder_top_left ( grid , size ) ;
hx_place_finder ( grid , size , 0 , size - 7 ) ;
hx_place_finder ( grid , size , size - 7 , 0 ) ;
hx_place_finder_bottom_right ( grid , size ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Add finder pattern separator region */
for ( i = 0 ; i < 8 ; i + + ) {
/* Top left */
grid [ ( 7 * size ) + i ] = 0x10 ;
grid [ ( i * size ) + 7 ] = 0x10 ;
2016-09-06 00:06:50 +03:00
/* Top right */
grid [ ( 7 * size ) + ( size - i - 1 ) ] = 0x10 ;
2016-04-09 19:01:21 +03:00
grid [ ( ( size - i - 1 ) * size ) + 7 ] = 0x10 ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Bottom left */
grid [ ( i * size ) + ( size - 8 ) ] = 0x10 ;
grid [ ( ( size - 8 ) * size ) + i ] = 0x10 ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Bottom right */
grid [ ( ( size - 8 ) * size ) + ( size - i - 1 ) ] = 0x10 ;
grid [ ( ( size - i - 1 ) * size ) + ( size - 8 ) ] = 0x10 ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Reserve function information region */
for ( i = 0 ; i < 9 ; i + + ) {
/* Top left */
grid [ ( 8 * size ) + i ] = 0x10 ;
grid [ ( i * size ) + 8 ] = 0x10 ;
2016-09-06 00:06:50 +03:00
/* Top right */
grid [ ( 8 * size ) + ( size - i - 1 ) ] = 0x10 ;
2016-04-09 19:01:21 +03:00
grid [ ( ( size - i - 1 ) * size ) + 8 ] = 0x10 ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Bottom left */
grid [ ( i * size ) + ( size - 9 ) ] = 0x10 ;
grid [ ( ( size - 9 ) * size ) + i ] = 0x10 ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Bottom right */
grid [ ( ( size - 9 ) * size ) + ( size - i - 1 ) ] = 0x10 ;
grid [ ( ( size - i - 1 ) * size ) + ( size - 9 ) ] = 0x10 ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
if ( version > 3 ) {
2021-10-31 00:00:31 +03:00
const int k = hx_module_k [ version - 1 ] ;
const int r = hx_module_r [ version - 1 ] ;
const int m = hx_module_m [ version - 1 ] ;
2016-04-09 19:01:21 +03:00
int x , y , row_switch , column_switch ;
int module_height , module_width ;
int mod_x , mod_y ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Add assistant alignment patterns to left and right */
y = 0 ;
mod_y = 0 ;
do {
if ( mod_y < m ) {
module_height = k ;
} else {
module_height = r - 1 ;
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ( mod_y & 1 ) = = 0 ) {
if ( ( m & 1 ) = = 1 ) {
2016-04-09 19:01:21 +03:00
hx_plot_assistant ( grid , size , 0 , y ) ;
}
} else {
2020-11-27 15:54:44 +03:00
if ( ( m & 1 ) = = 0 ) {
2016-04-09 19:01:21 +03:00
hx_plot_assistant ( grid , size , 0 , y ) ;
}
hx_plot_assistant ( grid , size , size - 1 , y ) ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
mod_y + + ;
y + = module_height ;
} while ( y < size ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Add assistant alignment patterns to top and bottom */
x = ( size - 1 ) ;
mod_x = 0 ;
do {
if ( mod_x < m ) {
module_width = k ;
} else {
module_width = r - 1 ;
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ( mod_x & 1 ) = = 0 ) {
if ( ( m & 1 ) = = 1 ) {
2016-04-09 19:01:21 +03:00
hx_plot_assistant ( grid , size , x , ( size - 1 ) ) ;
}
} else {
2020-11-27 15:54:44 +03:00
if ( ( m & 1 ) = = 0 ) {
2016-04-09 19:01:21 +03:00
hx_plot_assistant ( grid , size , x , ( size - 1 ) ) ;
}
hx_plot_assistant ( grid , size , x , 0 ) ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
mod_x + + ;
x - = module_width ;
} while ( x > = 0 ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
/* Add alignment pattern */
column_switch = 1 ;
y = 0 ;
2016-09-06 00:06:50 +03:00
mod_y = 0 ;
2016-04-09 19:01:21 +03:00
do {
if ( mod_y < m ) {
module_height = k ;
} else {
module_height = r - 1 ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
if ( column_switch = = 1 ) {
row_switch = 1 ;
column_switch = 0 ;
} else {
row_switch = 0 ;
column_switch = 1 ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
x = ( size - 1 ) ;
mod_x = 0 ;
do {
if ( mod_x < m ) {
module_width = k ;
} else {
module_width = r - 1 ;
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
if ( row_switch = = 1 ) {
if ( ! ( y = = 0 & & x = = ( size - 1 ) ) ) {
hx_plot_alignment ( grid , size , x , y , module_width , module_height ) ;
}
row_switch = 0 ;
} else {
row_switch = 1 ;
}
mod_x + + ;
x - = module_width ;
} while ( x > = 0 ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
mod_y + + ;
y + = module_height ;
} while ( y < size ) ;
}
}
2016-04-16 14:57:45 +03:00
/* Calculate error correction codes */
2020-11-27 15:54:44 +03:00
static void hx_add_ecc ( unsigned char fullstream [ ] , const unsigned char datastream [ ] , const int data_codewords ,
const int version , const int ecc_level ) {
2016-04-16 14:57:45 +03:00
unsigned char data_block [ 180 ] ;
unsigned char ecc_block [ 36 ] ;
int i , j , block ;
int input_position = - 1 ;
int output_position = - 1 ;
2021-10-31 00:00:31 +03:00
const int table_d1_pos = ( ( version - 1 ) * 36 ) + ( ( ecc_level - 1 ) * 9 ) ;
2020-11-27 15:54:44 +03:00
rs_t rs ;
2022-07-14 18:01:30 +03:00
rs_init_gf ( & rs , 0x163 ) ; /* x^8 + x^6 + x^5 + x + 1 = 0 */
2016-09-06 00:06:50 +03:00
2016-04-16 14:57:45 +03:00
for ( i = 0 ; i < 3 ; i + + ) {
2021-10-31 00:00:31 +03:00
const int batch_size = hx_table_d1 [ table_d1_pos + ( 3 * i ) ] ;
const int data_length = hx_table_d1 [ table_d1_pos + ( 3 * i ) + 1 ] ;
const int ecc_length = hx_table_d1 [ table_d1_pos + ( 3 * i ) + 2 ] ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
rs_init_code ( & rs , ecc_length , 1 ) ;
2016-09-06 00:06:50 +03:00
for ( block = 0 ; block < batch_size ; block + + ) {
2016-04-16 14:57:45 +03:00
for ( j = 0 ; j < data_length ; j + + ) {
input_position + + ;
output_position + + ;
2019-12-08 19:15:34 +03:00
data_block [ j ] = input_position < data_codewords ? datastream [ input_position ] : 0 ;
fullstream [ output_position ] = data_block [ j ] ;
2016-04-16 14:57:45 +03:00
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
rs_encode ( & rs , data_length , data_block , ecc_block ) ;
2016-09-06 00:06:50 +03:00
2016-04-16 14:57:45 +03:00
for ( j = 0 ; j < ecc_length ; j + + ) {
output_position + + ;
fullstream [ output_position ] = ecc_block [ ecc_length - j - 1 ] ;
}
}
}
}
2020-11-27 15:54:44 +03:00
static void hx_set_function_info ( unsigned char * grid , const int size , const int version , const int ecc_level ,
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int bitmask , const int debug_print ) {
2020-11-27 15:54:44 +03:00
int i , j ;
char function_information [ 34 ] ;
unsigned char fi_cw [ 3 ] = { 0 } ;
unsigned char fi_ecc [ 4 ] ;
int bp = 0 ;
rs_t rs ;
/* Form function information string */
bp = bin_append_posn ( version + 20 , 8 , function_information , bp ) ;
bp = bin_append_posn ( ecc_level - 1 , 2 , function_information , bp ) ;
bp = bin_append_posn ( bitmask , 2 , function_information , bp ) ;
for ( i = 0 ; i < 3 ; i + + ) {
for ( j = 0 ; j < 4 ; j + + ) {
if ( function_information [ ( i * 4 ) + j ] = = ' 1 ' ) {
fi_cw [ i ] + = ( 0x08 > > j ) ;
}
}
}
rs_init_gf ( & rs , 0x13 ) ;
rs_init_code ( & rs , 4 , 1 ) ;
rs_encode ( & rs , 3 , fi_cw , fi_ecc ) ;
for ( i = 3 ; i > = 0 ; i - - ) {
bp = bin_append_posn ( fi_ecc [ i ] , 4 , function_information , bp ) ;
}
2022-04-10 13:12:18 +03:00
/* Previously added alternating filler pattern here (as does BWIPP) but not mentioned in ISO/IEC 20830:2021 and
does not appear in Figure 1 nor in the figures in Annex K ( although does appear in Figure 2 and Figures 4 - 9 )
nor in the AIM ITS / 04 - 023 : 2022 examples : so just clear */
2020-11-27 15:54:44 +03:00
for ( i = 28 ; i < 34 ; i + + ) {
2022-04-10 13:12:18 +03:00
function_information [ i ] = ' 0 ' ;
2020-11-27 15:54:44 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2021-06-19 15:11:23 +03:00
printf ( " Version: %d, ECC: %d, Mask: %d, Structural Info: %.34s \n " , version , ecc_level , bitmask ,
function_information ) ;
2020-11-27 15:54:44 +03:00
}
/* Add function information to symbol */
for ( i = 0 ; i < 9 ; i + + ) {
if ( function_information [ i ] = = ' 1 ' ) {
grid [ ( 8 * size ) + i ] = 0x01 ;
grid [ ( ( size - 8 - 1 ) * size ) + ( size - i - 1 ) ] = 0x01 ;
}
if ( function_information [ i + 8 ] = = ' 1 ' ) {
grid [ ( ( 8 - i ) * size ) + 8 ] = 0x01 ;
grid [ ( ( size - 8 - 1 + i ) * size ) + ( size - 8 - 1 ) ] = 0x01 ;
}
if ( function_information [ i + 17 ] = = ' 1 ' ) {
grid [ ( i * size ) + ( size - 1 - 8 ) ] = 0x01 ;
grid [ ( ( size - 1 - i ) * size ) + 8 ] = 0x01 ;
}
if ( function_information [ i + 25 ] = = ' 1 ' ) {
grid [ ( 8 * size ) + ( size - 1 - 8 + i ) ] = 0x01 ;
grid [ ( ( size - 1 - 8 ) * size ) + ( 8 - i ) ] = 0x01 ;
}
}
}
2016-04-16 14:57:45 +03:00
/* Rearrange data in batches of 13 codewords (section 5.8.2) */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
static void hx_make_picket_fence ( const unsigned char fullstream [ ] , unsigned char picket_fence [ ] ,
const int streamsize ) {
2016-04-16 14:57:45 +03:00
int i , start ;
int output_position = 0 ;
2017-10-23 22:37:52 +03:00
2016-04-16 14:57:45 +03:00
for ( start = 0 ; start < 13 ; start + + ) {
for ( i = start ; i < streamsize ; i + = 13 ) {
2021-07-07 15:58:04 +03:00
picket_fence [ output_position ] = fullstream [ i ] ;
output_position + + ;
2016-04-16 14:57:45 +03:00
}
}
}
2016-04-20 22:44:59 +03:00
/* Evaluate a bitmask according to table 9 */
2020-11-27 15:54:44 +03:00
static int hx_evaluate ( const unsigned char * local , const int size ) {
static const unsigned char h1010111 [ 7 ] = { 1 , 0 , 1 , 0 , 1 , 1 , 1 } ;
static const unsigned char h1110101 [ 7 ] = { 1 , 1 , 1 , 0 , 1 , 0 , 1 } ;
int x , y , r , block ;
2016-04-20 22:44:59 +03:00
int result = 0 ;
2020-11-27 15:54:44 +03:00
int state ;
2016-04-20 22:44:59 +03:00
int a , b , afterCount , beforeCount ;
2020-11-27 15:54:44 +03:00
/* Test 1: 1:1:1:1:3 or 3:1:1:1:1 ratio pattern in row/column */
2016-04-20 22:44:59 +03:00
/* Vertical */
for ( x = 0 ; x < size ; x + + ) {
2020-11-27 15:54:44 +03:00
for ( y = 0 ; y < = ( size - 7 ) ; y + + ) {
if ( local [ y * size + x ] & & local [ ( y + 1 ) * size + x ] ! = local [ ( y + 5 ) * size + x ] & &
local [ ( y + 2 ) * size + x ] & & ! local [ ( y + 3 ) * size + x ] & &
local [ ( y + 4 ) * size + x ] & & local [ ( y + 6 ) * size + x ] ) {
2016-04-20 22:44:59 +03:00
/* Pattern found, check before and after */
beforeCount = 0 ;
2020-11-27 15:54:44 +03:00
for ( b = ( y - 1 ) ; b > = ( y - 3 ) ; b - - ) {
if ( b < 0 ) { /* Count < edge as whitespace */
beforeCount = 3 ;
break ;
}
if ( local [ ( b * size ) + x ] ) {
break ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
beforeCount + + ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
if ( beforeCount = = 3 ) {
/* Pattern is preceded by light area 3 modules wide */
result + = 50 ;
} else {
afterCount = 0 ;
for ( a = ( y + 7 ) ; a < = ( y + 9 ) ; a + + ) {
if ( a > = size ) { /* Count > edge as whitespace */
afterCount = 3 ;
break ;
}
if ( local [ ( a * size ) + x ] ) {
2019-12-08 19:15:34 +03:00
break ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
afterCount + + ;
}
if ( afterCount = = 3 ) {
/* Pattern is followed by light area 3 modules wide */
result + = 50 ;
2016-04-20 22:44:59 +03:00
}
}
2020-11-27 15:54:44 +03:00
y + + ; /* Skip to next possible match */
2016-04-20 22:44:59 +03:00
}
}
}
/* Horizontal */
for ( y = 0 ; y < size ; y + + ) {
2020-11-27 15:54:44 +03:00
r = y * size ;
for ( x = 0 ; x < = ( size - 7 ) ; x + + ) {
if ( memcmp ( local + r + x , h1010111 , 7 ) = = 0 | | memcmp ( local + r + x , h1110101 , 7 ) = = 0 ) {
2016-04-20 22:44:59 +03:00
/* Pattern found, check before and after */
beforeCount = 0 ;
2020-11-27 15:54:44 +03:00
for ( b = ( x - 1 ) ; b > = ( x - 3 ) ; b - - ) {
if ( b < 0 ) { /* Count < edge as whitespace */
beforeCount = 3 ;
break ;
}
if ( local [ r + b ] ) {
break ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
beforeCount + + ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
if ( beforeCount = = 3 ) {
/* Pattern is preceded by light area 3 modules wide */
result + = 50 ;
} else {
afterCount = 0 ;
for ( a = ( x + 7 ) ; a < = ( x + 9 ) ; a + + ) {
if ( a > = size ) { /* Count > edge as whitespace */
afterCount = 3 ;
2019-12-08 19:15:34 +03:00
break ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
if ( local [ r + a ] ) {
break ;
}
afterCount + + ;
}
if ( afterCount = = 3 ) {
/* Pattern is followed by light area 3 modules wide */
result + = 50 ;
2016-04-20 22:44:59 +03:00
}
}
2020-11-27 15:54:44 +03:00
x + + ; /* Skip to next possible match */
2016-04-20 22:44:59 +03:00
}
}
}
2016-09-06 00:06:50 +03:00
2016-04-20 22:44:59 +03:00
/* Test 2: Adjacent modules in row/column in same colour */
2016-06-19 11:07:50 +03:00
/* In AIMD-15 section 5.8.3.2 it is stated... “In Table 9 below, i refers to the row
* position of the module . ” - however i being the length of the run of the
* same colour ( i . e . " block " below ) in the same fashion as ISO / IEC 18004
2016-10-27 14:35:53 +03:00
* makes more sense . - - Confirmed by Wang Yi */
2022-04-10 13:12:18 +03:00
/* Fixed in ISO/IEC 20830 section 5.8.4.3 "In Table, i refers to the modules with
2021-06-19 15:11:23 +03:00
same color . " */
2016-09-06 00:06:50 +03:00
2016-04-20 22:44:59 +03:00
/* Vertical */
for ( x = 0 ; x < size ; x + + ) {
block = 0 ;
2019-12-08 19:15:34 +03:00
state = 0 ;
2016-04-20 22:44:59 +03:00
for ( y = 0 ; y < size ; y + + ) {
2020-11-27 15:54:44 +03:00
if ( local [ ( y * size ) + x ] = = state ) {
2016-04-20 22:44:59 +03:00
block + + ;
} else {
2019-12-08 19:15:34 +03:00
if ( block > = 3 ) {
2020-11-27 15:54:44 +03:00
result + = block * 4 ;
2016-04-20 22:44:59 +03:00
}
2019-12-08 19:15:34 +03:00
block = 1 ;
2016-04-20 22:44:59 +03:00
state = local [ ( y * size ) + x ] ;
}
}
2019-12-08 19:15:34 +03:00
if ( block > = 3 ) {
2020-11-27 15:54:44 +03:00
result + = block * 4 ;
2016-04-20 22:44:59 +03:00
}
}
/* Horizontal */
for ( y = 0 ; y < size ; y + + ) {
2020-11-27 15:54:44 +03:00
r = y * size ;
2016-04-20 22:44:59 +03:00
block = 0 ;
2020-11-27 15:54:44 +03:00
state = 0 ;
2016-04-20 22:44:59 +03:00
for ( x = 0 ; x < size ; x + + ) {
2020-11-27 15:54:44 +03:00
if ( local [ r + x ] = = state ) {
2016-04-20 22:44:59 +03:00
block + + ;
} else {
2019-12-08 19:15:34 +03:00
if ( block > = 3 ) {
2020-11-27 15:54:44 +03:00
result + = block * 4 ;
2016-04-20 22:44:59 +03:00
}
2019-12-08 19:15:34 +03:00
block = 1 ;
2020-11-27 15:54:44 +03:00
state = local [ r + x ] ;
2016-04-20 22:44:59 +03:00
}
}
2019-12-08 19:15:34 +03:00
if ( block > = 3 ) {
2020-11-27 15:54:44 +03:00
result + = block * 4 ;
2016-04-20 22:44:59 +03:00
}
}
return result ;
}
/* Apply the four possible bitmasks for evaluation */
2022-04-10 13:12:18 +03:00
/* TODO: Haven't been able to replicate (or even get close to) the penalty scores in ISO/IEC 20830:2021
* Annex K examples */
2020-11-27 15:54:44 +03:00
static void hx_apply_bitmask ( unsigned char * grid , const int size , const int version , const int ecc_level ,
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int user_mask , const int debug_print ) {
2016-04-20 22:44:59 +03:00
int x , y ;
2020-11-27 15:54:44 +03:00
int i , j , r , k ;
int pattern , penalty [ 4 ] = { 0 } ;
int best_pattern ;
2016-04-20 22:44:59 +03:00
int bit ;
2021-10-31 00:00:31 +03:00
const int size_squared = size * size ;
2022-07-14 18:01:30 +03:00
unsigned char * mask = ( unsigned char * ) z_alloca ( size_squared ) ;
unsigned char * local = ( unsigned char * ) z_alloca ( size_squared ) ;
2016-09-06 00:06:50 +03:00
2016-04-20 22:44:59 +03:00
/* Perform data masking */
2020-11-27 15:54:44 +03:00
memset ( mask , 0 , size_squared ) ;
for ( y = 0 ; y < size ; y + + ) {
r = y * size ;
for ( x = 0 ; x < size ; x + + ) {
k = r + x ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( ! ( grid [ k ] & 0xf0 ) ) {
j = x + 1 ;
i = y + 1 ;
if ( ( ( i + j ) & 1 ) = = 0 ) {
mask [ k ] | = 0x02 ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
if ( ( ( ( ( i + j ) % 3 ) + ( j % 3 ) ) & 1 ) = = 0 ) {
mask [ k ] | = 0x04 ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
if ( ( ( ( i % j ) + ( j % i ) + ( i % 3 ) + ( j % 3 ) ) & 1 ) = = 0 ) {
mask [ k ] | = 0x08 ;
2016-04-20 22:44:59 +03:00
}
}
}
}
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
if ( user_mask ) {
best_pattern = user_mask - 1 ;
} else {
2022-07-14 18:01:30 +03:00
/* apply data masks to grid, result in local */
2016-04-20 22:44:59 +03:00
2020-11-27 15:54:44 +03:00
/* Do null pattern 00 separately first */
pattern = 0 ;
for ( k = 0 ; k < size_squared ; k + + ) {
local [ k ] = grid [ k ] & 0x0f ;
2016-04-20 22:44:59 +03:00
}
2020-11-27 15:54:44 +03:00
/* Set the Structural Info */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_set_function_info ( local , size , version , ecc_level , pattern , 0 /*debug_print*/ ) ;
2020-11-27 15:54:44 +03:00
/* Evaluate result */
penalty [ pattern ] = hx_evaluate ( local , size ) ;
best_pattern = 0 ;
for ( pattern = 1 ; pattern < 4 ; pattern + + ) {
bit = 1 < < pattern ;
for ( k = 0 ; k < size_squared ; k + + ) {
if ( mask [ k ] & bit ) {
local [ k ] = grid [ k ] ^ 0x01 ;
} else {
local [ k ] = grid [ k ] & 0x0f ;
}
}
/* Set the Structural Info */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_set_function_info ( local , size , version , ecc_level , pattern , 0 /*debug_print*/ ) ;
2016-09-06 00:06:50 +03:00
2020-11-27 15:54:44 +03:00
/* Evaluate result */
penalty [ pattern ] = hx_evaluate ( local , size ) ;
if ( penalty [ pattern ] < penalty [ best_pattern ] ) {
best_pattern = pattern ;
}
}
2016-04-20 22:44:59 +03:00
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2020-11-27 15:54:44 +03:00
printf ( " Mask: %d (%s) " , best_pattern , user_mask ? " specified " : " automatic " ) ;
if ( ! user_mask ) {
for ( pattern = 0 ; pattern < 4 ; pattern + + ) printf ( " %d:%d " , pattern , penalty [ pattern ] ) ;
2016-04-20 22:44:59 +03:00
}
2023-06-12 03:25:55 +03:00
fputc ( ' \n ' , stdout ) ;
2016-04-20 22:44:59 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-20 22:44:59 +03:00
/* Apply mask */
2020-11-27 15:54:44 +03:00
if ( best_pattern ) { /* If not null mask */
if ( ! user_mask & & best_pattern = = 3 ) { /* Reuse last */
memcpy ( grid , local , size_squared ) ;
} else {
bit = 1 < < best_pattern ;
for ( k = 0 ; k < size_squared ; k + + ) {
if ( mask [ k ] & bit ) {
grid [ k ] ^ = 0x01 ;
2016-04-20 22:44:59 +03:00
}
}
}
}
2020-11-27 15:54:44 +03:00
/* Set the Structural Info */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_set_function_info ( grid , size , version , ecc_level , best_pattern , debug_print ) ;
2016-04-20 22:44:59 +03:00
}
2016-04-08 00:30:37 +03:00
/* Han Xin Code - main */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
INTERNAL int hanxin ( struct zint_symbol * symbol , struct zint_seg segs [ ] , const int seg_count ) {
2022-04-10 13:12:18 +03:00
int warn_number = 0 ;
2016-04-08 00:30:37 +03:00
int est_binlen ;
2016-04-30 12:25:16 +03:00
int ecc_level = symbol - > option_1 ;
2020-11-27 15:54:44 +03:00
int i , j , j_max , version ;
2020-04-02 16:41:13 +03:00
int full_multibyte ;
2020-11-27 15:54:44 +03:00
int user_mask ;
2016-09-04 18:35:11 +03:00
int data_codewords = 0 , size ;
2020-11-27 15:54:44 +03:00
int size_squared ;
2017-04-10 10:06:53 +03:00
int codewords ;
int bin_len ;
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
const int debug_print = symbol - > debug & ZINT_DEBUG_PRINT ;
const int eci_length_segs = get_eci_length_segs ( segs , seg_count ) ;
2022-07-14 18:01:30 +03:00
struct zint_seg * local_segs = ( struct zint_seg * ) z_alloca ( sizeof ( struct zint_seg ) * seg_count ) ;
unsigned int * ddata = ( unsigned int * ) z_alloca ( sizeof ( unsigned int ) * eci_length_segs ) ;
char * mode = ( char * ) z_alloca ( eci_length_segs ) ;
2021-01-11 21:11:41 +03:00
char * binary ;
2016-09-06 00:06:50 +03:00
unsigned char * datastream ;
2016-08-16 14:43:41 +03:00
unsigned char * fullstream ;
unsigned char * picket_fence ;
unsigned char * grid ;
2016-09-06 00:06:50 +03:00
2022-05-19 12:17:51 +03:00
segs_cpy ( symbol , segs , seg_count , local_segs ) ; /* Shallow copy (needed to set default ECI & protect lengths) */
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
2021-01-11 21:11:41 +03:00
/* If ZINT_FULL_MULTIBYTE set use Hanzi mode in DATA_MODE or for non-GB 18030 in UNICODE_MODE */
2020-11-27 15:54:44 +03:00
full_multibyte = ( symbol - > option_3 & 0xFF ) = = ZINT_FULL_MULTIBYTE ;
user_mask = ( symbol - > option_3 > > 8 ) & 0x0F ; /* User mask is pattern + 1, so >= 1 and <= 4 */
if ( user_mask > 4 ) {
user_mask = 0 ; /* Ignore */
}
2020-04-02 16:41:13 +03:00
2019-12-08 19:15:34 +03:00
if ( ( symbol - > input_mode & 0x07 ) = = DATA_MODE ) {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
gb18030_cpy_segs ( local_segs , seg_count , ddata , full_multibyte ) ;
2016-08-16 14:43:41 +03:00
} else {
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
unsigned int * dd = ddata ;
for ( i = 0 ; i < seg_count ; i + + ) {
int done = 0 ;
if ( local_segs [ i ] . eci ! = 32 | | seg_count > 1 ) { /* Unless ECI 32 (GB 18030) or have multiple segments */
/* Try other conversions (ECI 0 defaults to ISO/IEC 8859-1) */
int error_number = gb18030_utf8_to_eci ( local_segs [ i ] . eci , local_segs [ i ] . source , & local_segs [ i ] . length ,
dd , full_multibyte ) ;
if ( error_number = = 0 ) {
done = 1 ;
} else if ( local_segs [ i ] . eci | | seg_count > 1 ) {
sprintf ( symbol - > errtxt , " 545: Invalid character in input data for ECI %d " , local_segs [ i ] . eci ) ;
return error_number ;
}
2017-04-23 22:15:50 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( ! done ) {
/* Try GB 18030 */
int error_number = gb18030_utf8 ( symbol , local_segs [ i ] . source , & local_segs [ i ] . length , dd ) ;
if ( error_number ! = 0 ) {
return error_number ;
}
if ( local_segs [ i ] . eci ! = 32 ) {
strcpy ( symbol - > errtxt , " 543: Converted to GB 18030 but no ECI specified " ) ;
warn_number = ZINT_WARN_NONCOMPLIANT ;
}
2022-04-10 13:12:18 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
dd + = local_segs [ i ] . length ;
2016-08-16 14:43:41 +03:00
}
2016-05-02 00:10:50 +03:00
}
2016-04-08 00:30:37 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_define_mode_segs ( mode , ddata , local_segs , seg_count , debug_print ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
est_binlen = hx_calc_binlen_segs ( mode , ddata , local_segs , seg_count ) ;
2016-09-06 00:06:50 +03:00
2022-07-14 18:01:30 +03:00
binary = ( char * ) z_alloca ( ( est_binlen + 1 ) ) ;
2016-09-06 00:06:50 +03:00
2016-04-30 12:25:16 +03:00
if ( ( ecc_level < = 0 ) | | ( ecc_level > = 5 ) ) {
ecc_level = 1 ;
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_calculate_binary_segs ( binary , mode , ddata , local_segs , seg_count , & bin_len , debug_print ) ;
2020-11-27 15:54:44 +03:00
codewords = bin_len > > 3 ;
if ( bin_len & 0x07 ) {
2017-04-10 10:06:53 +03:00
codewords + + ;
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-12-09 13:07:11 +03:00
printf ( " Num. of codewords: %d (%d padbits) \n " , codewords , bin_len & 0x07 ) ;
2022-04-10 13:12:18 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
version = 85 ;
for ( i = 84 ; i > 0 ; i - - ) {
switch ( ecc_level ) {
case 1 :
2022-04-10 13:12:18 +03:00
if ( hx_data_codewords_L1 [ i - 1 ] > = codewords ) {
2016-04-09 19:01:21 +03:00
version = i ;
2016-04-10 22:36:57 +03:00
data_codewords = hx_data_codewords_L1 [ i - 1 ] ;
2016-04-09 19:01:21 +03:00
}
break ;
case 2 :
2022-04-10 13:12:18 +03:00
if ( hx_data_codewords_L2 [ i - 1 ] > = codewords ) {
2016-04-09 19:01:21 +03:00
version = i ;
2016-04-10 22:36:57 +03:00
data_codewords = hx_data_codewords_L2 [ i - 1 ] ;
2016-04-09 19:01:21 +03:00
}
break ;
case 3 :
2022-04-10 13:12:18 +03:00
if ( hx_data_codewords_L3 [ i - 1 ] > = codewords ) {
2016-04-09 19:01:21 +03:00
version = i ;
2016-04-10 22:36:57 +03:00
data_codewords = hx_data_codewords_L3 [ i - 1 ] ;
2016-04-09 19:01:21 +03:00
}
break ;
case 4 :
2022-04-10 13:12:18 +03:00
if ( hx_data_codewords_L4 [ i - 1 ] > = codewords ) {
2016-04-09 19:01:21 +03:00
version = i ;
2016-04-10 22:36:57 +03:00
data_codewords = hx_data_codewords_L4 [ i - 1 ] ;
2016-04-09 19:01:21 +03:00
}
break ;
2021-08-10 14:04:25 +03:00
default : /* Not reached */
2016-09-06 00:06:50 +03:00
assert ( 0 ) ;
break ;
2016-04-09 19:01:21 +03:00
}
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
if ( version = = 85 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 541: Input too long for selected error correction level " ) ;
2016-04-09 19:01:21 +03:00
return ZINT_ERROR_TOO_LONG ;
}
2016-09-06 00:06:50 +03:00
2016-04-30 12:25:16 +03:00
if ( ( symbol - > option_2 < 0 ) | | ( symbol - > option_2 > 84 ) ) {
symbol - > option_2 = 0 ;
}
2016-09-06 00:06:50 +03:00
2016-04-30 12:25:16 +03:00
if ( symbol - > option_2 > version ) {
version = symbol - > option_2 ;
}
2017-10-23 22:37:52 +03:00
2017-04-11 11:26:39 +03:00
if ( ( symbol - > option_2 ! = 0 ) & & ( symbol - > option_2 < version ) ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 542: Input too long for selected symbol size " ) ;
2017-04-11 11:26:39 +03:00
return ZINT_ERROR_TOO_LONG ;
}
2016-09-06 00:06:50 +03:00
2016-04-30 12:25:16 +03:00
/* If there is spare capacity, increase the level of ECC */
2016-09-06 00:06:50 +03:00
2021-06-19 15:11:23 +03:00
/* Unless explicitly specified (within min/max bounds) by user */
if ( symbol - > option_1 = = - 1 | | symbol - > option_1 ! = ecc_level ) {
2022-04-10 13:12:18 +03:00
if ( ( ecc_level = = 1 ) & & ( codewords < = hx_data_codewords_L2 [ version - 1 ] ) ) {
2019-12-08 19:15:34 +03:00
ecc_level = 2 ;
data_codewords = hx_data_codewords_L2 [ version - 1 ] ;
}
2016-08-22 20:07:27 +03:00
2022-04-10 13:12:18 +03:00
if ( ( ecc_level = = 2 ) & & ( codewords < = hx_data_codewords_L3 [ version - 1 ] ) ) {
2019-12-08 19:15:34 +03:00
ecc_level = 3 ;
data_codewords = hx_data_codewords_L3 [ version - 1 ] ;
}
2016-08-22 20:07:27 +03:00
2022-04-10 13:12:18 +03:00
if ( ( ecc_level = = 3 ) & & ( codewords < = hx_data_codewords_L4 [ version - 1 ] ) ) {
2019-12-08 19:15:34 +03:00
ecc_level = 4 ;
data_codewords = hx_data_codewords_L4 [ version - 1 ] ;
}
2016-04-30 12:25:16 +03:00
}
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
size = ( version * 2 ) + 21 ;
2020-11-27 15:54:44 +03:00
size_squared = size * size ;
2016-04-16 14:57:45 +03:00
2022-07-14 18:01:30 +03:00
datastream = ( unsigned char * ) z_alloca ( data_codewords ) ;
fullstream = ( unsigned char * ) z_alloca ( hx_total_codewords [ version - 1 ] ) ;
picket_fence = ( unsigned char * ) z_alloca ( hx_total_codewords [ version - 1 ] ) ;
grid = ( unsigned char * ) z_alloca ( size_squared ) ;
2016-04-16 14:57:45 +03:00
2020-11-27 15:54:44 +03:00
memset ( datastream , 0 , data_codewords ) ;
2016-09-06 00:06:50 +03:00
2017-04-10 10:06:53 +03:00
for ( i = 0 ; i < bin_len ; i + + ) {
2016-04-10 22:36:57 +03:00
if ( binary [ i ] = = ' 1 ' ) {
2020-11-27 15:54:44 +03:00
datastream [ i > > 3 ] | = 0x80 > > ( i & 0x07 ) ;
2016-04-10 22:36:57 +03:00
}
}
2016-04-16 14:57:45 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
printf ( " Datastream (%d): " , data_codewords ) ;
2019-11-17 17:56:43 +03:00
for ( i = 0 ; i < data_codewords ; i + + ) {
2023-06-12 03:25:55 +03:00
printf ( " %.2x " , datastream [ i ] ) ;
2019-11-17 17:56:43 +03:00
}
2023-06-12 03:25:55 +03:00
fputc ( ' \n ' , stdout ) ;
2019-11-17 17:56:43 +03:00
}
2019-12-19 03:37:55 +03:00
# ifdef ZINT_TEST
2019-12-16 20:31:52 +03:00
if ( symbol - > debug & ZINT_DEBUG_TEST ) debug_test_codeword_dump ( symbol , datastream , data_codewords ) ;
2019-12-19 03:37:55 +03:00
# endif
2019-11-17 17:56:43 +03:00
2016-04-09 19:01:21 +03:00
hx_setup_grid ( grid , size , version ) ;
2016-09-06 00:06:50 +03:00
2019-12-08 19:15:34 +03:00
hx_add_ecc ( fullstream , datastream , data_codewords , version , ecc_level ) ;
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
if ( debug_print ) {
2023-06-12 03:25:55 +03:00
printf ( " Fullstream (%d): " , hx_total_codewords [ version - 1 ] ) ;
2022-04-10 13:12:18 +03:00
for ( i = 0 ; i < hx_total_codewords [ version - 1 ] ; i + + ) {
2023-06-12 03:25:55 +03:00
printf ( " %.2x " , fullstream [ i ] ) ;
2022-04-10 13:12:18 +03:00
}
2023-06-12 03:25:55 +03:00
fputc ( ' \n ' , stdout ) ;
2022-04-10 13:12:18 +03:00
}
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_make_picket_fence ( fullstream , picket_fence , hx_total_codewords [ version - 1 ] ) ;
2016-09-06 00:06:50 +03:00
2016-04-20 22:44:59 +03:00
/* Populate grid */
j = 0 ;
2020-11-27 15:54:44 +03:00
j_max = hx_total_codewords [ version - 1 ] * 8 ;
for ( i = 0 ; i < size_squared ; i + + ) {
2016-04-20 22:44:59 +03:00
if ( grid [ i ] = = 0x00 ) {
2020-11-27 15:54:44 +03:00
if ( j < j_max ) {
if ( picket_fence [ ( j > > 3 ) ] & ( 0x80 > > ( j & 0x07 ) ) ) {
2016-04-20 22:44:59 +03:00
grid [ i ] = 0x01 ;
}
j + + ;
2016-04-23 17:26:51 +03:00
} else {
2020-11-27 15:54:44 +03:00
break ;
2016-04-23 17:26:51 +03:00
}
}
}
2016-09-06 00:06:50 +03:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA
RMQR: fix ECI encoding (wrong bit length for indicator)
MICROQR: check versions M1 and M2 for allowed characters so as to give
better error messages
DOTCODE: some small optimizations
common.c: add is_chr(), segs_length(), segs_cpy()
CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add
namespace prefixes to static funcs/data
includes: use Z_ prefix, unuse double underscore prefixes (guard defines)
manual.txt: compress some tables using double/treble column sets
2022-05-09 21:50:50 +03:00
hx_apply_bitmask ( grid , size , version , ecc_level , user_mask , debug_print ) ;
2016-09-06 00:06:50 +03:00
2016-04-09 19:01:21 +03:00
symbol - > width = size ;
symbol - > rows = size ;
for ( i = 0 ; i < size ; i + + ) {
2021-10-31 00:00:31 +03:00
const int r = i * size ;
2016-04-09 19:01:21 +03:00
for ( j = 0 ; j < size ; j + + ) {
2020-11-27 15:54:44 +03:00
if ( grid [ r + j ] & 0x01 ) {
2016-04-09 19:01:21 +03:00
set_module ( symbol , i , j ) ;
}
}
symbol - > row_height [ i ] = 1 ;
}
2021-06-19 15:11:23 +03:00
symbol - > height = size ;
2016-04-16 14:57:45 +03:00
2022-04-10 13:12:18 +03:00
return warn_number ;
2016-09-06 00:06:50 +03:00
}
2022-04-10 13:12:18 +03:00
/* vim: set ts=4 sw=4 et : */