PageRenderTime 1525ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/harbour-3.0.0/contrib/hbzebra/code128.c

#
C | 399 lines | 299 code | 28 blank | 72 comment | 84 complexity | 654d1803af5afb5fa223af24ae929eec MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause, CC-BY-SA-3.0, LGPL-3.0, GPL-2.0, LGPL-2.0, LGPL-2.1
  1. /*
  2. * $Id: code128.c 15829 2010-11-17 11:19:59Z druzus $
  3. */
  4. /*
  5. * Harbour Project source code:
  6. * Zebra barcode library
  7. *
  8. * Copyright 2010 Mindaugas Kavaliauskas <dbtopas at dbtopas.lt>
  9. * www - http://harbour-project.org
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2, or (at your option)
  14. * any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this software; see the file COPYING. If not, write to
  23. * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  24. * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
  25. *
  26. * As a special exception, the Harbour Project gives permission for
  27. * additional uses of the text contained in its release of Harbour.
  28. *
  29. * The exception is that, if you link the Harbour libraries with other
  30. * files to produce an executable, this does not by itself cause the
  31. * resulting executable to be covered by the GNU General Public License.
  32. * Your use of that executable is in no way restricted on account of
  33. * linking the Harbour library code into it.
  34. *
  35. * This exception does not however invalidate any other reasons why
  36. * the executable file might be covered by the GNU General Public License.
  37. *
  38. * This exception applies only to the code released by the Harbour
  39. * Project under the name Harbour. If you copy code from other
  40. * Harbour Project or Free Software Foundation releases into a copy of
  41. * Harbour, as the General Public License permits, the exception does
  42. * not apply to the code that you add in this way. To avoid misleading
  43. * anyone as to the status of such modified files, you must delete
  44. * this exception notice from them.
  45. *
  46. * If you write modifications of your own for Harbour, it is your choice
  47. * whether to permit this exception to apply to your modifications.
  48. * If you do not wish that, delete this exception notice.
  49. *
  50. */
  51. #include "hbzebra.h"
  52. #include "hbapiitm.h"
  53. #include "hbapierr.h"
  54. static const unsigned short s_code[] = {
  55. 00633, /* 00 */
  56. 00663, /* ! ! 01 */
  57. 01463, /* " " 02 */
  58. 00311, /* # # 03 */
  59. 00611, /* $ $ 04 */
  60. 00621, /* % % 05 */
  61. 00231, /* & & 06 */
  62. 00431, /* ' ' 07 */
  63. 00461, /* ( ( 08 */
  64. 00223, /* ) ) 09 */
  65. 00423, /* * * 10 */
  66. 00443, /* + + 11 */
  67. 00715, /* , , 12 */
  68. 00731, /* - - 13 */
  69. 01631, /* . . 14 */
  70. 00635, /* / / 15 */
  71. 00671, /* 0 0 16 */
  72. 01471, /* 1 1 17 */
  73. 01163, /* 2 2 18 */
  74. 00723, /* 3 3 19 */
  75. 01623, /* 4 4 20 */
  76. 00473, /* 5 5 21 */
  77. 00563, /* 6 6 22 */
  78. 01667, /* 7 7 23 */
  79. 00627, /* 8 8 24 */
  80. 00647, /* 9 9 25 */
  81. 01447, /* : : 26 */
  82. 00467, /* ; ; 27 */
  83. 00547, /* < < 28 */
  84. 01147, /* = = 29 */
  85. 00333, /* > > 30 */
  86. 01433, /* ? ? 31 */
  87. 01543, /* @ @ 32 */
  88. 00305, /* A A 33 */
  89. 00321, /* B B 34 */
  90. 01421, /* C C 35 */
  91. 00215, /* D D 36 */
  92. 00261, /* E E 37 */
  93. 01061, /* F F 38 */
  94. 00213, /* G G 39 */
  95. 00243, /* H H 40 */
  96. 01043, /* I I 41 */
  97. 00355, /* J J 42 */
  98. 01615, /* K K 43 */
  99. 01661, /* L L 44 */
  100. 00335, /* M M 45 */
  101. 01435, /* N N 46 */
  102. 01561, /* O O 47 */
  103. 01567, /* P P 48 */
  104. 01613, /* Q Q 49 */
  105. 01643, /* R R 50 */
  106. 00273, /* S S 51 */
  107. 01073, /* T T 52 */
  108. 01673, /* U U 53 */
  109. 00327, /* V V 54 */
  110. 01427, /* W W 55 */
  111. 01507, /* X X 56 */
  112. 00267, /* Y Y 57 */
  113. 01067, /* Z Z 58 */
  114. 01307, /* [ [ 59 */
  115. 01367, /* \ \ 60 */
  116. 01023, /* ] ] 61 */
  117. 01217, /* ^ ^ 62 */
  118. 00145, /* _ _ 63 */
  119. 00605, /* NUL ` 64 */
  120. 00151, /* SOH a 65 */
  121. 01411, /* STX b 66 */
  122. 00641, /* ETX c 67 */
  123. 01441, /* EOT d 68 */
  124. 00115, /* ENQ e 69 */
  125. 00415, /* ACK f 70 */
  126. 00131, /* BEL g 71 */
  127. 01031, /* BS h 72 */
  128. 00541, /* HT i 73 */
  129. 01141, /* LF j 74 */
  130. 01103, /* VT k 75 */
  131. 00123, /* FF l 76 */
  132. 01357, /* CR m 77 */
  133. 00503, /* SO n 78 */
  134. 01361, /* SI o 79 */
  135. 00745, /* DLE p 80 */
  136. 00751, /* DC1 q 81 */
  137. 01711, /* DC2 r 82 */
  138. 00475, /* DC3 s 83 */
  139. 00571, /* DC4 t 84 */
  140. 01171, /* NAK u 85 */
  141. 00457, /* SYN v 86 */
  142. 00517, /* ETB w 87 */
  143. 01117, /* CAN x 88 */
  144. 01733, /* EM y 89 */
  145. 01573, /* SUB z 90 */
  146. 01557, /* ESC { 91 */
  147. 00365, /* FS | 92 */
  148. 01705, /* GS } 93 */
  149. 01721, /* RS ~ 94 */
  150. 00275, /* US DEL 95 */
  151. 01075, /* FNC3 FNC3 96 */
  152. 00257, /* FNC2 FNC2 97 */
  153. 01057, /* ShiB ShiA 98 */
  154. 01735, /* CodC CodC 99 */
  155. 01675, /* CodB FNC4 CodB 100 */
  156. 01727, /* FNC4 CodA CodA 101 */
  157. 01657, /* FNC1 FNC1 FNC1 102 */
  158. 00413, /* Start Code A 103 */
  159. 00113, /* Start Code B 104 */
  160. 00713}; /* Start Code C 105 */
  161. #define CODESET_A 0
  162. #define CODESET_B 1
  163. #define START_A 103
  164. #define START_B 104
  165. #define START_C 105
  166. #define SELECT_A 101
  167. #define SELECT_B 100
  168. #define SELECT_C 99
  169. #define SHIFT_AB 98
  170. static int _code128_charno( char ch, int iCodeSet )
  171. {
  172. if( iCodeSet == CODESET_A )
  173. {
  174. if( ch >= ' ' && ch <= '_' )
  175. return ch - ' ';
  176. else if( ( unsigned char ) ch <= 31 )
  177. return ch + 64;
  178. else
  179. return -1;
  180. }
  181. else if( iCodeSet == CODESET_B )
  182. {
  183. if( ch >= ' ' && ( unsigned char ) ch <= 127 )
  184. return ch - ' ';
  185. else
  186. return -1;
  187. }
  188. return -1;
  189. }
  190. PHB_ZEBRA hb_zebra_create_code128( const char * szCode, HB_SIZE nLen, int iFlags )
  191. {
  192. PHB_ZEBRA pZebra;
  193. int i, j, k, csum, iCode, iCodeSet, iCodeLen, iLen = ( int ) nLen;
  194. int * pCode;
  195. HB_SYMBOL_UNUSED( iFlags );
  196. pZebra = hb_zebra_create();
  197. pZebra->iType = HB_ZEBRA_TYPE_CODE128;
  198. j = 0;
  199. for( i = 0; i < iLen; i++ )
  200. {
  201. if( ( unsigned char ) szCode[ i ] >= 128 )
  202. {
  203. pZebra->iError = HB_ZEBRA_ERROR_INVALIDCODE;
  204. return pZebra;
  205. }
  206. if( szCode[ i ] >= ' ' && szCode[ i ] <= 126 )
  207. j++;
  208. }
  209. /* make print string */
  210. pZebra->szCode = ( char * ) hb_xgrab( j + 1 );
  211. j = 0;
  212. for( i = 0; i < iLen; i++ )
  213. {
  214. if( szCode[ i ] >= 32 && szCode[ i ] <= 126 )
  215. pZebra->szCode[ j++ ] = szCode[ i ];
  216. }
  217. pZebra->szCode[ j ] = '\0';
  218. /* generate code set switch characters */
  219. pCode = ( int * ) hb_xgrab( sizeof( int ) * iLen * 2 );
  220. iCodeSet = CODESET_B; /* to pacify MSVC warning only. It will be assigned later */
  221. iCodeLen = 0;
  222. /* determine the first optimal codeset */
  223. for( i = 0; i < iLen; i++ )
  224. {
  225. if( _code128_charno( szCode[ i ], CODESET_A ) == -1 )
  226. {
  227. iCodeSet = CODESET_B;
  228. pCode[ iCodeLen++ ] = START_B;
  229. break;
  230. }
  231. else if( _code128_charno( szCode[ i ], CODESET_B ) == -1 )
  232. {
  233. iCodeSet = CODESET_A;
  234. pCode[ iCodeLen++ ] = START_A;
  235. break;
  236. }
  237. }
  238. if( iCodeLen == 0 )
  239. {
  240. iCodeSet = CODESET_B;
  241. pCode[ iCodeLen++ ] = START_B;
  242. }
  243. /* encode source data */
  244. /* Warning: digit optimizer works in optimal way with this encoder code. Be careful
  245. if you'll change encoder code, digit optimizer canm require adjustment also [Mindaugas] */
  246. for( i = 0; i < iLen; i++ )
  247. {
  248. iCode = _code128_charno( szCode[ i ], iCodeSet );
  249. if( iCode != -1 )
  250. pCode[ iCodeLen++ ] = iCode;
  251. else
  252. {
  253. /* We should generate codeset switch instead of shift for the last character.
  254. This will help digit optimizer to do its job [Mindaugas] */
  255. if( i + 1 < iLen &&
  256. _code128_charno( szCode[ i + 1 ], iCodeSet == CODESET_A ? CODESET_B : CODESET_A ) == -1 )
  257. {
  258. pCode[ iCodeLen++ ] = SHIFT_AB;
  259. pCode[ iCodeLen++ ] = _code128_charno( szCode[ i ], iCodeSet == CODESET_A ? CODESET_B : CODESET_A );
  260. }
  261. else
  262. {
  263. if( iCodeSet == CODESET_A )
  264. {
  265. iCodeSet = CODESET_B;
  266. pCode[ iCodeLen++ ] = SELECT_B;
  267. }
  268. else
  269. {
  270. iCodeSet = CODESET_A;
  271. pCode[ iCodeLen++ ] = SELECT_A;
  272. }
  273. pCode[ iCodeLen++ ] = _code128_charno( szCode[ i ], iCodeSet );
  274. }
  275. }
  276. }
  277. /* optimize digits */
  278. iCodeSet = pCode[ 0 ] == START_A ? CODESET_A : CODESET_B;
  279. for( i = 1; i < iCodeLen; i++ )
  280. {
  281. if( iCodeSet == CODESET_A && pCode[ i ] == SELECT_B )
  282. iCodeSet = CODESET_B;
  283. else if( iCodeSet == CODESET_B && pCode[ i ] == SELECT_A )
  284. iCodeSet = CODESET_A;
  285. if( 16 <= pCode[ i ] && pCode[ i ] <= 25 )
  286. {
  287. for( j = i + 1; j < iCodeLen && 16 <= pCode[ j ] && pCode[ j ] <= 25; j++ );
  288. if( j - i == 2 && i == 1 && j == iCodeLen )
  289. {
  290. /* [StartB] 1 2 --> [StartC] [12] */
  291. pCode[ 0 ] = START_C;
  292. pCode[ 1 ] = ( pCode[ 1 ] - 16 ) * 10 + pCode[ 2 ] - 16;
  293. iCodeLen = 2;
  294. break;
  295. }
  296. else if( ( j - i >= 4 && ( i == 1 || j == iCodeLen || pCode[ j ] == SELECT_A || pCode[ j ] == SELECT_B ) ) ||
  297. j - i >= 6 )
  298. {
  299. if( i == 1 )
  300. {
  301. /* [StartN] 1 2 3 4 --> [StartC] [12] [34] */
  302. /* [StartN] 1 2 3 4 5 --> [StartC] [12] [34] [CodeN] 5 */
  303. /* [StartN] 1 2 3 4 X ... --> [StartC] [12] [34] [CodeN] X ... */
  304. /* [StartN] 1 2 3 4 5 X ... --> [StartC] [12] [34] [CodeN] 5 X ... */
  305. pCode[ 0 ] = START_C;
  306. for( k = 1; k < j - 1; k += 2 )
  307. pCode[ i++ ] = ( pCode[ k ] - 16 ) * 10 + pCode[ k + 1 ] - 16;
  308. if( k < iCodeLen )
  309. {
  310. j = i;
  311. pCode[ i++ ] = iCodeSet == CODESET_A ? SELECT_A : SELECT_B;
  312. for( ; k < iCodeLen; k++ )
  313. pCode[ i++ ] = pCode[ k ];
  314. }
  315. iCodeLen = i;
  316. }
  317. else
  318. {
  319. /* ... X 1 2 3 4 --> ... X [CodeC] [12] [34] */
  320. /* ... X 1 2 3 4 [CodeN] ... --> ... X [CodeC] [12] [34] [CodeN] ... */
  321. /* ... X 1 2 3 4 5 --> ... X 1 [CodeC] [23] [45] */
  322. /* ... X 1 2 3 4 5 [CodeN] ... --> ... X 1 [CodeC] [23] [45] [CodeN] ... */
  323. /* ... X 1 2 3 4 5 6 Y ... --> ... X [CodeC] [12] [34] [56] [CodeN] Y ... */
  324. /* ... X 1 2 3 4 5 6 7 Y ... --> ... X 1 [CodeC] [23] [45] [67] [CodeN] Y ... */
  325. if( ( j - i ) & 1 )
  326. {
  327. /* digit count is odd */
  328. i++;
  329. }
  330. pCode[ i + 1 ] = ( pCode[ i ] - 16 ) * 10 + pCode[ i + 1 ] - 16;
  331. pCode[ i ] = SELECT_C;
  332. i += 2;
  333. for( k = i; k < j; k += 2 )
  334. pCode[ i++ ] = ( pCode[ k ] - 16 ) * 10 + pCode[ k + 1 ] - 16;
  335. j = i;
  336. if( k < iCodeLen )
  337. {
  338. if( pCode[ k ] != SELECT_A && pCode[ k ] != SELECT_B )
  339. pCode[ i++ ] = iCodeSet == CODESET_A ? SELECT_A : SELECT_B;
  340. for( ; k < iCodeLen; k++ )
  341. pCode[ i++ ] = pCode[ k ];
  342. }
  343. iCodeLen = i;
  344. }
  345. }
  346. i = j - 1;
  347. }
  348. }
  349. pZebra->pBits = hb_bitbuffer_create();
  350. csum = pCode[ 0 ];
  351. for( i = 0; i < iCodeLen; i++ )
  352. {
  353. hb_bitbuffer_cat_int( pZebra->pBits, s_code[ pCode[ i ] ], 11 );
  354. csum += i * pCode[ i ];
  355. }
  356. hb_xfree( pCode );
  357. /* checksum */
  358. hb_bitbuffer_cat_int( pZebra->pBits, s_code[ csum % 103 ], 11 );
  359. hb_bitbuffer_cat_int( pZebra->pBits, 0x1AE3, 13 );
  360. return pZebra;
  361. }
  362. HB_FUNC( HB_ZEBRA_CREATE_CODE128 )
  363. {
  364. PHB_ITEM pItem = hb_param( 1, HB_IT_STRING );
  365. if( pItem )
  366. {
  367. hb_zebra_ret( hb_zebra_create_code128( hb_itemGetCPtr( pItem ), hb_itemGetCLen( pItem ), hb_parni( 2 ) ) );
  368. }
  369. else
  370. hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  371. }