2008-07-14 01:15:55 +04:00
/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */
2016-02-20 13:50:15 +03:00
/*
libzint - the open source barcode library
2017-08-27 11:31:02 +03:00
Copyright ( C ) 2008 - 2017 Robin Stuart < rstuart114 @ gmail . com >
2008-07-18 18:35:32 +04:00
Including bug fixes by Bryan Hatton
2013-05-16 21:26:38 +04:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
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 .
2016-02-20 13:50:15 +03:00
*/
2008-07-14 01:15:55 +04:00
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
2009-06-03 00:23:38 +04:00
# ifdef _MSC_VER
# include <malloc.h>
# endif
2008-07-14 01:15:55 +04:00
# include "common.h"
2009-03-14 14:04:52 +03:00
# define DAFTSET "DAFT"
2008-07-14 01:15:55 +04:00
# define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2009-03-14 14:04:52 +03:00
# define KASUTSET "1234567890-abcdefgh"
# define CHKASUTSET "0123456789-abcdefgh"
# define SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2008-07-14 01:15:55 +04:00
/* PostNet number encoding table - In this table L is long as S is short */
2016-02-20 13:50:15 +03:00
static const char * PNTable [ 10 ] = {
" LLSSS " , " SSSLL " , " SSLSL " , " SSLLS " , " SLSSL " , " SLSLS " , " SLLSS " , " LSSSL " ,
" LSSLS " , " LSLSS "
} ;
static const char * PLTable [ 10 ] = {
" SSLLL " , " LLLSS " , " LLSLS " , " LLSSL " , " LSLLS " , " LSLSL " , " LSSLL " , " SLLLS " ,
" SLLSL " , " SLSLL "
} ;
static const char * RoyalValues [ 36 ] = {
" 11 " , " 12 " , " 13 " , " 14 " , " 15 " , " 10 " , " 21 " , " 22 " , " 23 " , " 24 " , " 25 " ,
" 20 " , " 31 " , " 32 " , " 33 " , " 34 " , " 35 " , " 30 " , " 41 " , " 42 " , " 43 " , " 44 " , " 45 " , " 40 " , " 51 " , " 52 " ,
" 53 " , " 54 " , " 55 " , " 50 " , " 01 " , " 02 " , " 03 " , " 04 " , " 05 " , " 00 "
} ;
2008-07-14 01:15:55 +04:00
2008-09-16 11:46:22 +04:00
/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */
2016-02-20 13:50:15 +03:00
static const char * RoyalTable [ 36 ] = {
" 3300 " , " 3210 " , " 3201 " , " 2310 " , " 2301 " , " 2211 " , " 3120 " , " 3030 " , " 3021 " ,
" 2130 " , " 2121 " , " 2031 " , " 3102 " , " 3012 " , " 3003 " , " 2112 " , " 2103 " , " 2013 " , " 1320 " , " 1230 " ,
" 1221 " , " 0330 " , " 0321 " , " 0231 " , " 1302 " , " 1212 " , " 1203 " , " 0312 " , " 0303 " , " 0213 " , " 1122 " ,
" 1032 " , " 1023 " , " 0132 " , " 0123 " , " 0033 "
} ;
static const char * FlatTable [ 10 ] = {
" 0504 " , " 18 " , " 0117 " , " 0216 " , " 0315 " , " 0414 " , " 0513 " , " 0612 " , " 0711 " , " 0810 "
} ;
static const char * KoreaTable [ 10 ] = {
" 1313150613 " , " 0713131313 " , " 0417131313 " , " 1506131313 " ,
" 0413171313 " , " 17171313 " , " 1315061313 " , " 0413131713 " , " 17131713 " , " 13171713 "
} ;
static const char * JapanTable [ 19 ] = {
" 114 " , " 132 " , " 312 " , " 123 " , " 141 " , " 321 " , " 213 " , " 231 " , " 411 " , " 144 " ,
" 414 " , " 324 " , " 342 " , " 234 " , " 432 " , " 243 " , " 423 " , " 441 " , " 111 "
} ;
/* Handles the PostNet system used for Zip codes in the US */
int postnet ( struct zint_symbol * symbol , unsigned char source [ ] , char dest [ ] , int length ) {
unsigned int i , sum , check_digit ;
int error_number ;
error_number = 0 ;
if ( length > 38 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 480: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
error_number = is_sane ( NEON , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 481: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
sum = 0 ;
/* start character */
strcpy ( dest , " L " ) ;
for ( i = 0 ; i < length ; i + + ) {
lookup ( NEON , PNTable , source [ i ] , dest ) ;
sum + = ctoi ( source [ i ] ) ;
}
check_digit = ( 10 - ( sum % 10 ) ) % 10 ;
2016-03-03 00:12:38 +03:00
strcat ( dest , PNTable [ check_digit ] ) ;
2016-02-20 13:50:15 +03:00
/* stop character */
2016-03-03 00:12:38 +03:00
strcat ( dest , " L " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
2008-07-14 01:15:55 +04:00
}
2012-12-31 17:41:59 +04:00
2016-02-20 13:50:15 +03:00
/* Puts PostNet barcodes into the pattern matrix */
int post_plot ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
char height_pattern [ 256 ] ; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
unsigned int loopey , h ;
int writer ;
int error_number ;
error_number = 0 ;
error_number = postnet ( symbol , source , height_pattern , length ) ;
if ( error_number ! = 0 ) {
return error_number ;
}
writer = 0 ;
h = strlen ( height_pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( height_pattern [ loopey ] = = ' L ' ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
writer + = 3 ;
}
symbol - > row_height [ 0 ] = 6 ;
symbol - > row_height [ 1 ] = 6 ;
symbol - > rows = 2 ;
symbol - > width = writer - 1 ;
return error_number ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Handles the PLANET system used for item tracking in the US */
int planet ( struct zint_symbol * symbol , unsigned char source [ ] , char dest [ ] , int length ) {
unsigned int i , sum , check_digit ;
int error_number ;
error_number = 0 ;
if ( length > 38 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 482: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
error_number = is_sane ( NEON , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 483: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
sum = 0 ;
/* start character */
strcpy ( dest , " L " ) ;
for ( i = 0 ; i < length ; i + + ) {
lookup ( NEON , PLTable , source [ i ] , dest ) ;
sum + = ctoi ( source [ i ] ) ;
}
check_digit = ( 10 - ( sum % 10 ) ) % 10 ;
2016-03-03 00:12:38 +03:00
strcat ( dest , PLTable [ check_digit ] ) ;
2016-02-20 13:50:15 +03:00
/* stop character */
2016-03-03 00:12:38 +03:00
strcat ( dest , " L " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Puts PLANET barcodes into the pattern matrix */
int planet_plot ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
char height_pattern [ 256 ] ; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
unsigned int loopey , h ;
int writer ;
int error_number ;
error_number = 0 ;
error_number = planet ( symbol , source , height_pattern , length ) ;
if ( error_number ! = 0 ) {
return error_number ;
}
writer = 0 ;
h = strlen ( height_pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( height_pattern [ loopey ] = = ' L ' ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
writer + = 3 ;
}
symbol - > row_height [ 0 ] = 6 ;
symbol - > row_height [ 1 ] = 6 ;
symbol - > rows = 2 ;
symbol - > width = writer - 1 ;
return error_number ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Korean Postal Authority */
2016-03-03 00:12:38 +03:00
int korea_post ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-02-20 13:50:15 +03:00
int total , loop , check , zeroes , error_number ;
char localstr [ 8 ] , dest [ 80 ] ;
error_number = 0 ;
if ( length > 6 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 484: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
error_number = is_sane ( NEON , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 485: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
zeroes = 6 - length ;
memset ( localstr , ' 0 ' , zeroes ) ;
strcpy ( localstr + zeroes , ( char * ) source ) ;
total = 0 ;
for ( loop = 0 ; loop < 6 ; loop + + ) {
total + = ctoi ( localstr [ loop ] ) ;
}
check = 10 - ( total % 10 ) ;
if ( check = = 10 ) {
check = 0 ;
}
localstr [ 6 ] = itoc ( check ) ;
localstr [ 7 ] = ' \0 ' ;
* dest = ' \0 ' ;
for ( loop = 5 ; loop > = 0 ; loop - - ) {
lookup ( NEON , KoreaTable , localstr [ loop ] , dest ) ;
}
lookup ( NEON , KoreaTable , localstr [ 6 ] , dest ) ;
expand ( symbol , dest ) ;
ustrcpy ( symbol - > text , ( unsigned char * ) localstr ) ;
return error_number ;
2008-12-07 23:11:50 +03:00
}
2016-02-20 13:50:15 +03:00
/* The simplest barcode symbology ever! Supported by MS Word, so here it is!
glyphs from http : //en.wikipedia.org/wiki/Facing_Identification_Mark */
int fim ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-03-03 00:12:38 +03:00
2016-02-20 13:50:15 +03:00
char dest [ 16 ] = { 0 } ;
if ( length > 1 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 486: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
switch ( ( char ) source [ 0 ] ) {
case ' a ' :
case ' A ' :
strcpy ( dest , " 111515111 " ) ;
break ;
case ' b ' :
case ' B ' :
strcpy ( dest , " 13111311131 " ) ;
break ;
case ' c ' :
case ' C ' :
strcpy ( dest , " 11131313111 " ) ;
break ;
case ' d ' :
case ' D ' :
strcpy ( dest , " 1111131311111 " ) ;
break ;
default :
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 487: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_INVALID_DATA ;
break ;
}
expand ( symbol , dest ) ;
return 0 ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Handles the 4 State barcodes used in the UK by Royal Mail */
char rm4scc ( char source [ ] , unsigned char dest [ ] , int length ) {
unsigned int i ;
int top , bottom , row , column , check_digit ;
char values [ 3 ] , set_copy [ ] = KRSET ;
top = 0 ;
bottom = 0 ;
/* start character */
strcpy ( ( char * ) dest , " 1 " ) ;
for ( i = 0 ; i < length ; i + + ) {
lookup ( KRSET , RoyalTable , source [ i ] , ( char * ) dest ) ;
strcpy ( values , RoyalValues [ posn ( KRSET , source [ i ] ) ] ) ;
top + = ctoi ( values [ 0 ] ) ;
bottom + = ctoi ( values [ 1 ] ) ;
}
/* Calculate the check digit */
row = ( top % 6 ) - 1 ;
column = ( bottom % 6 ) - 1 ;
if ( row = = - 1 ) {
row = 5 ;
}
if ( column = = - 1 ) {
column = 5 ;
}
check_digit = ( 6 * row ) + column ;
2016-03-03 00:12:38 +03:00
strcat ( ( char * ) dest , RoyalTable [ check_digit ] ) ;
2016-02-20 13:50:15 +03:00
/* stop character */
2016-03-03 00:12:38 +03:00
strcat ( ( char * ) dest , " 0 " ) ;
2016-02-20 13:50:15 +03:00
return set_copy [ check_digit ] ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Puts RM4SCC into the data matrix */
int royal_plot ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-08-29 20:45:58 +03:00
char height_pattern [ 210 ] ;
2016-02-20 13:50:15 +03:00
unsigned int loopey , h ;
int writer ;
int error_number ;
strcpy ( height_pattern , " " ) ;
error_number = 0 ;
2016-08-29 20:45:58 +03:00
if ( length > 50 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 488: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
to_upper ( source ) ;
error_number = is_sane ( KRSET , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 489: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
/*check = */ rm4scc ( ( char * ) source , ( unsigned char * ) height_pattern , length ) ;
2016-08-29 20:45:58 +03:00
2016-02-20 13:50:15 +03:00
writer = 0 ;
h = strlen ( height_pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( ( height_pattern [ loopey ] = = ' 1 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
if ( ( height_pattern [ loopey ] = = ' 2 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 2 , writer ) ;
}
writer + = 2 ;
}
symbol - > row_height [ 0 ] = 3 ;
symbol - > row_height [ 1 ] = 2 ;
symbol - > row_height [ 2 ] = 3 ;
symbol - > rows = 3 ;
symbol - > width = writer - 1 ;
return error_number ;
2008-07-14 01:15:55 +04:00
}
2016-02-20 13:50:15 +03:00
/* Handles Dutch Post TNT KIX symbols
The same as RM4SCC but without check digit
Specification at http : //www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */
int kix_code ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-08-29 20:45:58 +03:00
char height_pattern [ 75 ] , localstr [ 20 ] ;
2016-02-20 13:50:15 +03:00
unsigned int loopey ;
int writer , i , h ;
int error_number ; /* zeroes; */
strcpy ( height_pattern , " " ) ;
error_number = 0 ;
if ( length > 18 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 490: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
to_upper ( source ) ;
error_number = is_sane ( KRSET , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 491: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
strcpy ( localstr , ( char * ) source ) ;
2016-08-29 20:45:58 +03:00
2016-02-20 13:50:15 +03:00
/* Encode data */
2016-08-29 20:45:58 +03:00
for ( i = 0 ; i < length ; i + + ) {
2016-02-20 13:50:15 +03:00
lookup ( KRSET , RoyalTable , localstr [ i ] , height_pattern ) ;
}
writer = 0 ;
h = strlen ( height_pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( ( height_pattern [ loopey ] = = ' 1 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
if ( ( height_pattern [ loopey ] = = ' 2 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 2 , writer ) ;
}
writer + = 2 ;
}
symbol - > row_height [ 0 ] = 3 ;
symbol - > row_height [ 1 ] = 2 ;
symbol - > row_height [ 2 ] = 3 ;
symbol - > rows = 3 ;
symbol - > width = writer - 1 ;
return error_number ;
2008-09-16 11:46:22 +04:00
}
2016-02-20 13:50:15 +03:00
/* Handles DAFT Code symbols */
int daft_code ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
char height_pattern [ 100 ] ;
unsigned int loopey , h ;
int writer , i , error_number ;
strcpy ( height_pattern , " " ) ;
error_number = 0 ;
if ( length > 50 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 492: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
to_upper ( ( unsigned char * ) source ) ;
error_number = is_sane ( DAFTSET , ( unsigned char * ) source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 493: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
for ( i = 0 ; i < length ; i + + ) {
if ( source [ i ] = = ' D ' ) {
2016-03-03 00:12:38 +03:00
strcat ( height_pattern , " 2 " ) ;
2016-02-20 13:50:15 +03:00
}
if ( source [ i ] = = ' A ' ) {
2016-03-03 00:12:38 +03:00
strcat ( height_pattern , " 1 " ) ;
2016-02-20 13:50:15 +03:00
}
if ( source [ i ] = = ' F ' ) {
2016-03-03 00:12:38 +03:00
strcat ( height_pattern , " 0 " ) ;
2016-02-20 13:50:15 +03:00
}
if ( source [ i ] = = ' T ' ) {
2016-03-03 00:12:38 +03:00
strcat ( height_pattern , " 3 " ) ;
2016-02-20 13:50:15 +03:00
}
}
writer = 0 ;
h = strlen ( height_pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( ( height_pattern [ loopey ] = = ' 1 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
if ( ( height_pattern [ loopey ] = = ' 2 ' ) | | ( height_pattern [ loopey ] = = ' 0 ' ) ) {
set_module ( symbol , 2 , writer ) ;
}
writer + = 2 ;
}
symbol - > row_height [ 0 ] = 3 ;
symbol - > row_height [ 1 ] = 2 ;
symbol - > row_height [ 2 ] = 3 ;
symbol - > rows = 3 ;
symbol - > width = writer - 1 ;
return error_number ;
2008-09-02 23:47:26 +04:00
}
2016-02-20 13:50:15 +03:00
/* Flattermarken - Not really a barcode symbology! */
2016-03-03 00:12:38 +03:00
int flattermarken ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-02-20 13:50:15 +03:00
int loop , error_number ;
char dest [ 512 ] ; /* 90 * 4 + 1 ~ */
error_number = 0 ;
if ( length > 90 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 494: Input too long " ) ;
2016-02-20 13:50:15 +03:00
return ZINT_ERROR_TOO_LONG ;
}
error_number = is_sane ( NEON , source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 495: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
* dest = ' \0 ' ;
for ( loop = 0 ; loop < length ; loop + + ) {
lookup ( NEON , FlatTable , source [ loop ] , dest ) ;
}
expand ( symbol , dest ) ;
return error_number ;
2008-07-14 01:15:55 +04:00
}
2009-03-14 14:04:52 +03:00
2016-02-20 13:50:15 +03:00
/* Japanese Postal Code (Kasutama Barcode) */
2016-03-03 00:12:38 +03:00
int japan_post ( struct zint_symbol * symbol , unsigned char source [ ] , int length ) {
2016-02-20 13:50:15 +03:00
int error_number , h ;
char pattern [ 69 ] ;
int writer , loopey , inter_posn , i , sum , check ;
char check_char ;
char inter [ 23 ] ;
2009-09-29 13:45:46 +04:00
2009-06-03 00:23:38 +04:00
# ifndef _MSC_VER
2016-02-20 13:50:15 +03:00
char local_source [ length + 1 ] ;
2009-06-03 00:23:38 +04:00
# else
2016-02-20 13:50:15 +03:00
char * local_source = ( char * ) _alloca ( length + 1 ) ;
2009-06-03 00:23:38 +04:00
# endif
2016-02-20 13:50:15 +03:00
2016-08-29 20:45:58 +03:00
if ( length > 20 ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 496: Input too long " ) ;
2016-08-29 20:45:58 +03:00
return ZINT_ERROR_TOO_LONG ;
}
2016-02-20 13:50:15 +03:00
inter_posn = 0 ;
error_number = 0 ;
strcpy ( local_source , ( char * ) source ) ;
for ( i = 0 ; i < length ; i + + ) {
local_source [ i ] = source [ i ] ;
}
to_upper ( ( unsigned char * ) local_source ) ;
error_number = is_sane ( SHKASUTSET , ( unsigned char * ) local_source , length ) ;
if ( error_number = = ZINT_ERROR_INVALID_DATA ) {
2017-07-27 18:01:53 +03:00
strcpy ( symbol - > errtxt , " 497: Invalid characters in data " ) ;
2016-02-20 13:50:15 +03:00
return error_number ;
}
memset ( inter , ' d ' , 20 ) ; /* Pad character CC4 */
inter [ 20 ] = ' \0 ' ;
i = 0 ;
inter_posn = 0 ;
do {
if ( ( ( local_source [ i ] > = ' 0 ' ) & & ( local_source [ i ] < = ' 9 ' ) ) | | ( local_source [ i ] = = ' - ' ) ) {
inter [ inter_posn ] = local_source [ i ] ;
inter_posn + + ;
} else {
if ( ( local_source [ i ] > = ' A ' ) & & ( local_source [ i ] < = ' J ' ) ) {
inter [ inter_posn ] = ' a ' ;
inter [ inter_posn + 1 ] = local_source [ i ] - ' A ' + ' 0 ' ;
inter_posn + = 2 ;
}
if ( ( local_source [ i ] > = ' K ' ) & & ( local_source [ i ] < = ' T ' ) ) {
inter [ inter_posn ] = ' b ' ;
inter [ inter_posn + 1 ] = local_source [ i ] - ' K ' + ' 0 ' ;
inter_posn + = 2 ;
}
if ( ( local_source [ i ] > = ' U ' ) & & ( local_source [ i ] < = ' Z ' ) ) {
inter [ inter_posn ] = ' c ' ;
inter [ inter_posn + 1 ] = local_source [ i ] - ' U ' + ' 0 ' ;
inter_posn + = 2 ;
}
}
i + + ;
} while ( ( i < length ) & & ( inter_posn < 20 ) ) ;
inter [ 20 ] = ' \0 ' ;
strcpy ( pattern , " 13 " ) ; /* Start */
sum = 0 ;
for ( i = 0 ; i < 20 ; i + + ) {
2016-03-03 00:12:38 +03:00
strcat ( pattern , JapanTable [ posn ( KASUTSET , inter [ i ] ) ] ) ;
2016-02-20 13:50:15 +03:00
sum + = posn ( CHKASUTSET , inter [ i ] ) ;
}
/* Calculate check digit */
check = 19 - ( sum % 19 ) ;
if ( check = = 19 ) {
check = 0 ;
}
if ( check < = 9 ) {
check_char = check + ' 0 ' ;
}
if ( check = = 10 ) {
check_char = ' - ' ;
}
if ( check > = 11 ) {
check_char = ( check - 11 ) + ' a ' ;
}
2016-03-03 00:12:38 +03:00
strcat ( pattern , JapanTable [ posn ( KASUTSET , check_char ) ] ) ;
2016-02-20 13:50:15 +03:00
2016-03-03 00:12:38 +03:00
strcat ( pattern , " 31 " ) ; /* Stop */
2016-02-20 13:50:15 +03:00
/* Resolve pattern to 4-state symbols */
writer = 0 ;
h = strlen ( pattern ) ;
for ( loopey = 0 ; loopey < h ; loopey + + ) {
if ( ( pattern [ loopey ] = = ' 2 ' ) | | ( pattern [ loopey ] = = ' 1 ' ) ) {
set_module ( symbol , 0 , writer ) ;
}
set_module ( symbol , 1 , writer ) ;
if ( ( pattern [ loopey ] = = ' 3 ' ) | | ( pattern [ loopey ] = = ' 1 ' ) ) {
set_module ( symbol , 2 , writer ) ;
}
writer + = 2 ;
}
symbol - > row_height [ 0 ] = 3 ;
symbol - > row_height [ 1 ] = 2 ;
symbol - > row_height [ 2 ] = 3 ;
symbol - > rows = 3 ;
symbol - > width = writer - 1 ;
return error_number ;
2009-03-14 14:04:52 +03:00
}