source: trunk/Packages/lazbarcodes/src/lbc_pdf417.pas

Last change on this file was 123, checked in by chronos, 3 years ago
  • Added: QR code image visible in contact others tab. It can be saved as image to file.
File size: 61.2 KB
Line 
1{ lbc_pdf417 - Handles PDF-417 bar codes
2
3 Based on Zint (done by Robin Stuart and the Zint team)
4 http://github.com/zint/zint
5 and Pascal adaption by TheUnknownOnes
6 http://theunknownones.net
7
8 Refactoring: W. Pamler
9}
10
11unit lbc_pdf417;
12
13{$IFDEF FPC}
14{$mode objfpc}{$H+}
15{$ENDIF}
16
17interface
18
19uses
20 SysUtils, Types, zint;
21
22function pdf417(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
23function pdf417enc(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
24function micro_pdf417(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
25
26implementation
27
28uses
29 lbc_helper;
30
31const
32 TEX = 900;
33 BYT = 901;
34 NUM = 902;
35 _FALSE = 0;
36 _TRUE = 1;
37
38const
39 BRSET: String = 'ABCDEFabcdefghijklmnopqrstuvwxyz*+-';
40
41const
42 { Left and Right Row Address Pattern from Table 2 }
43 RAPLR: array[0..52] of String = (
44 '', '221311', '311311', '312211', '222211', '213211', '214111', '223111',
45 '313111', '322111', '412111', '421111', '331111', '241111', '232111', '231211', '321211',
46 '411211', '411121', '411112', '321112', '312112', '311212', '311221', '311131', '311122',
47 '311113', '221113', '221122', '221131', '221221', '222121', '312121', '321121', '231121',
48 '231112', '222112', '213112', '212212', '212221', '212131', '212122', '212113', '211213',
49 '211123', '211132', '211141', '211231', '211222', '211312', '211321', '211411', '212311'
50 );
51
52{ Centre Row Address Pattern from Table 2 }
53 RAPC: array[0..52] of String = (
54 '', '112231', '121231', '122131', '131131', '131221', '132121', '141121',
55 '141211', '142111', '133111', '132211', '131311', '122311', '123211', '124111', '115111',
56 '114211', '114121', '123121', '123112', '122212', '122221', '121321', '121411', '112411',
57 '113311', '113221', '113212', '113122', '122122', '131122', '131113', '122113', '113113',
58 '112213', '112222', '112312', '112321', '111421', '111331', '111322', '111232', '111223',
59 '111133', '111124', '111214', '112114', '121114', '121123', '121132', '112132', '112141'
60 );
61
62 { PDF417 error correction coefficients from Grand Zebu }
63 coefrs : array[0..1021] of Integer = (
64 { k = 2 }
65 27, 917,
66
67 { k = 4 }
68 522, 568, 723, 809,
69
70 { k = 8 }
71 237, 308, 436, 284, 646, 653, 428, 379,
72
73 { k = 16 }
74 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
75
76 { k = 32 }
77 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517,
78 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
79
80 { k = 64 }
81 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612,
82 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184,
83 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502,
84 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543,
85
86 { k = 128 }
87 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415,
88 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704,
89 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569,
90 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776,
91 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898,
92 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616,
93 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34,
94 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539,
95
96 { k = 256 }
97 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720,
98 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757,
99 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137,
100 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884,
101 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521,
102 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470,
103 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90,
104 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134,
105 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234,
106 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621,
107 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528,
108 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550,
109 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754,
110 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532,
111 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173,
112 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10,
113
114 { k = 512 }
115 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492,
116 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781,
117 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534,
118 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41,
119 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741,
120 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142,
121 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258,
122 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303,
123 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402,
124 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785,
125 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543,
126 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820,
127 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578,
128 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911,
129 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408,
130 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729,
131 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772,
132 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777,
133 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45,
134 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905,
135 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341,
136 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808,
137 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249,
138 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791,
139 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437,
140 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842,
141 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316,
142 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656,
143 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433,
144 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780,
145 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647,
146 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263
147 );
148
149 { Converts values into bar patterns - replacing Grand Zebu's true type font }
150 PDFttf : array[0..34] of String = (
151 '00000', '00001', '00010', '00011', '00100', '00101', '00110', '00111',
152 '01000', '01001', '01010', '01011', '01100', '01101', '01110', '01111', '10000', '10001',
153 '10010', '10011', '10100', '10101', '10110', '10111', '11000', '11001', '11010',
154 '11011', '11100', '11101', '11110', '11111', '01', '1111111101010100', '11111101000101001');
155
156 { MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F }
157 Microcoeffs : array[0..343] of Integer = (
158 { k = 7 }
159 76, 925, 537, 597, 784, 691, 437,
160
161 { k = 8 }
162 237, 308, 436, 284, 646, 653, 428, 379,
163
164 { k = 9 }
165 567, 527, 622, 257, 289, 362, 501, 441, 205,
166
167 { k = 10 }
168 377, 457, 64, 244, 826, 841, 818, 691, 266, 612,
169
170 { k = 11 }
171 462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904,
172
173 { k = 12 }
174 597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851,
175
176 { k = 13 }
177 764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692,
178
179 { k = 14 }
180 669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215,
181
182 { k = 15 }
183 460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642,
184
185 { k = 16 }
186 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
187
188 { k = 18 }
189 279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756,
190 760, 573,
191
192 { k = 21 }
193 108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691,
194 347, 165, 193, 259, 568,
195
196 { k = 26 }
197 443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893,
198 699, 245, 441, 454, 325, 858, 131, 847, 764, 169,
199
200 { k = 32 }
201 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517,
202 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
203
204 { k = 38 }
205 234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684,
206 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771,
207 554, 289, 231, 125, 117, 518,
208
209 { k = 44 }
210 476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405,
211 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213,
212 31, 560, 231, 758, 103, 271, 572, 436, 339, 730, 82, 285,
213
214 { k = 50 }
215 923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303,
216 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26,
217 579, 623, 766, 146, 10, 739, 246, 127, 71, 244, 211, 477, 920, 876, 427, 820,
218 718, 435
219 );
220 { rows, columns, error codewords, k-offset of valid MicroPDF417 sizes from ISO/IEC 24728:2006 }
221
222 MicroVariants: array[0..135] of Integer = (
223 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
224 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44,
225 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50,
226 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294
227 );
228 { rows, columns, error codewords, k-offset }
229
230 { following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables 10, 11 and 12 }
231 RAPTable: array[0..135] of Integer = (
232 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1,
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25,
234 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49,
235 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 );
236
237 codagemc: array[0..2786] of String = (
238 'urA', 'xfs', 'ypy', 'unk', 'xdw', 'yoz', 'pDA', 'uls', 'pBk', 'eBA',
239 'pAs', 'eAk', 'prA', 'uvs', 'xhy', 'pnk', 'utw', 'xgz', 'fDA', 'pls', 'fBk', 'frA', 'pvs',
240 'uxy', 'fnk', 'ptw', 'uwz', 'fls', 'psy', 'fvs', 'pxy', 'ftw', 'pwz', 'fxy', 'yrx', 'ufk',
241 'xFw', 'ymz', 'onA', 'uds', 'xEy', 'olk', 'ucw', 'dBA', 'oks', 'uci', 'dAk', 'okg', 'dAc',
242 'ovk', 'uhw', 'xaz', 'dnA', 'ots', 'ugy', 'dlk', 'osw', 'ugj', 'dks', 'osi', 'dvk', 'oxw',
243 'uiz', 'dts', 'owy', 'dsw', 'owj', 'dxw', 'oyz', 'dwy', 'dwj', 'ofA', 'uFs', 'xCy', 'odk',
244 'uEw', 'xCj', 'clA', 'ocs', 'uEi', 'ckk', 'ocg', 'ckc', 'ckE', 'cvA', 'ohs', 'uay', 'ctk',
245 'ogw', 'uaj', 'css', 'ogi', 'csg', 'csa', 'cxs', 'oiy', 'cww', 'oij', 'cwi', 'cyy', 'oFk',
246 'uCw', 'xBj', 'cdA', 'oEs', 'uCi', 'cck', 'oEg', 'uCb', 'ccc', 'oEa', 'ccE', 'oED', 'chk',
247 'oaw', 'uDj', 'cgs', 'oai', 'cgg', 'oab', 'cga', 'cgD', 'obj', 'cib', 'cFA', 'oCs', 'uBi',
248 'cEk', 'oCg', 'uBb', 'cEc', 'oCa', 'cEE', 'oCD', 'cEC', 'cas', 'cag', 'caa', 'cCk', 'uAr',
249 'oBa', 'oBD', 'cCB', 'tfk', 'wpw', 'yez', 'mnA', 'tds', 'woy', 'mlk', 'tcw', 'woj', 'FBA',
250 'mks', 'FAk', 'mvk', 'thw', 'wqz', 'FnA', 'mts', 'tgy', 'Flk', 'msw', 'Fks', 'Fkg', 'Fvk',
251 'mxw', 'tiz', 'Fts', 'mwy', 'Fsw', 'Fsi', 'Fxw', 'myz', 'Fwy', 'Fyz', 'vfA', 'xps', 'yuy',
252 'vdk', 'xow', 'yuj', 'qlA', 'vcs', 'xoi', 'qkk', 'vcg', 'xob', 'qkc', 'vca', 'mfA', 'tFs',
253 'wmy', 'qvA', 'mdk', 'tEw', 'wmj', 'qtk', 'vgw', 'xqj', 'hlA', 'Ekk', 'mcg', 'tEb', 'hkk',
254 'qsg', 'hkc', 'EvA', 'mhs', 'tay', 'hvA', 'Etk', 'mgw', 'taj', 'htk', 'qww', 'vij', 'hss',
255 'Esg', 'hsg', 'Exs', 'miy', 'hxs', 'Eww', 'mij', 'hww', 'qyj', 'hwi', 'Eyy', 'hyy', 'Eyj',
256 'hyj', 'vFk', 'xmw', 'ytj', 'qdA', 'vEs', 'xmi', 'qck', 'vEg', 'xmb', 'qcc', 'vEa', 'qcE',
257 'qcC', 'mFk', 'tCw', 'wlj', 'qhk', 'mEs', 'tCi', 'gtA', 'Eck', 'vai', 'tCb', 'gsk', 'Ecc',
258 'mEa', 'gsc', 'qga', 'mED', 'EcC', 'Ehk', 'maw', 'tDj', 'gxk', 'Egs', 'mai', 'gws', 'qii',
259 'mab', 'gwg', 'Ega', 'EgD', 'Eiw', 'mbj', 'gyw', 'Eii', 'gyi', 'Eib', 'gyb', 'gzj', 'qFA',
260 'vCs', 'xli', 'qEk', 'vCg', 'xlb', 'qEc', 'vCa', 'qEE', 'vCD', 'qEC', 'qEB', 'EFA', 'mCs',
261 'tBi', 'ghA', 'EEk', 'mCg', 'tBb', 'ggk', 'qag', 'vDb', 'ggc', 'EEE', 'mCD', 'ggE', 'qaD',
262 'ggC', 'Eas', 'mDi', 'gis', 'Eag', 'mDb', 'gig', 'qbb', 'gia', 'EaD', 'giD', 'gji', 'gjb',
263 'qCk', 'vBg', 'xkr', 'qCc', 'vBa', 'qCE', 'vBD', 'qCC', 'qCB', 'ECk', 'mBg', 'tAr', 'gak',
264 'ECc', 'mBa', 'gac', 'qDa', 'mBD', 'gaE', 'ECC', 'gaC', 'ECB', 'EDg', 'gbg', 'gba', 'gbD',
265 'vAq', 'vAn', 'qBB', 'mAq', 'EBE', 'gDE', 'gDC', 'gDB', 'lfA', 'sps', 'wey', 'ldk', 'sow',
266 'ClA', 'lcs', 'soi', 'Ckk', 'lcg', 'Ckc', 'CkE', 'CvA', 'lhs', 'sqy', 'Ctk', 'lgw', 'sqj',
267 'Css', 'lgi', 'Csg', 'Csa', 'Cxs', 'liy', 'Cww', 'lij', 'Cwi', 'Cyy', 'Cyj', 'tpk', 'wuw',
268 'yhj', 'ndA', 'tos', 'wui', 'nck', 'tog', 'wub', 'ncc', 'toa', 'ncE', 'toD', 'lFk', 'smw',
269 'wdj', 'nhk', 'lEs', 'smi', 'atA', 'Cck', 'tqi', 'smb', 'ask', 'ngg', 'lEa', 'asc', 'CcE',
270 'asE', 'Chk', 'law', 'snj', 'axk', 'Cgs', 'trj', 'aws', 'nii', 'lab', 'awg', 'Cga', 'awa',
271 'Ciw', 'lbj', 'ayw', 'Cii', 'ayi', 'Cib', 'Cjj', 'azj', 'vpA', 'xus', 'yxi', 'vok', 'xug',
272 'yxb', 'voc', 'xua', 'voE', 'xuD', 'voC', 'nFA', 'tms', 'wti', 'rhA', 'nEk', 'xvi', 'wtb',
273 'rgk', 'vqg', 'xvb', 'rgc', 'nEE', 'tmD', 'rgE', 'vqD', 'nEB', 'CFA', 'lCs', 'sli', 'ahA',
274 'CEk', 'lCg', 'slb', 'ixA', 'agk', 'nag', 'tnb', 'iwk', 'rig', 'vrb', 'lCD', 'iwc', 'agE',
275 'naD', 'iwE', 'CEB', 'Cas', 'lDi', 'ais', 'Cag', 'lDb', 'iys', 'aig', 'nbb', 'iyg', 'rjb',
276 'CaD', 'aiD', 'Cbi', 'aji', 'Cbb', 'izi', 'ajb', 'vmk', 'xtg', 'ywr', 'vmc', 'xta', 'vmE',
277 'xtD', 'vmC', 'vmB', 'nCk', 'tlg', 'wsr', 'rak', 'nCc', 'xtr', 'rac', 'vna', 'tlD', 'raE',
278 'nCC', 'raC', 'nCB', 'raB', 'CCk', 'lBg', 'skr', 'aak', 'CCc', 'lBa', 'iik', 'aac', 'nDa',
279 'lBD', 'iic', 'rba', 'CCC', 'iiE', 'aaC', 'CCB', 'aaB', 'CDg', 'lBr', 'abg', 'CDa', 'ijg',
280 'aba', 'CDD', 'ija', 'abD', 'CDr', 'ijr', 'vlc', 'xsq', 'vlE', 'xsn', 'vlC', 'vlB', 'nBc',
281 'tkq', 'rDc', 'nBE', 'tkn', 'rDE', 'vln', 'rDC', 'nBB', 'rDB', 'CBc', 'lAq', 'aDc', 'CBE',
282 'lAn', 'ibc', 'aDE', 'nBn', 'ibE', 'rDn', 'CBB', 'ibC', 'aDB', 'ibB', 'aDq', 'ibq', 'ibn',
283 'xsf', 'vkl', 'tkf', 'nAm', 'nAl', 'CAo', 'aBo', 'iDo', 'CAl', 'aBl', 'kpk', 'BdA', 'kos',
284 'Bck', 'kog', 'seb', 'Bcc', 'koa', 'BcE', 'koD', 'Bhk', 'kqw', 'sfj', 'Bgs', 'kqi', 'Bgg',
285 'kqb', 'Bga', 'BgD', 'Biw', 'krj', 'Bii', 'Bib', 'Bjj', 'lpA', 'sus', 'whi', 'lok', 'sug',
286 'loc', 'sua', 'loE', 'suD', 'loC', 'BFA', 'kms', 'sdi', 'DhA', 'BEk', 'svi', 'sdb', 'Dgk',
287 'lqg', 'svb', 'Dgc', 'BEE', 'kmD', 'DgE', 'lqD', 'BEB', 'Bas', 'kni', 'Dis', 'Bag', 'knb',
288 'Dig', 'lrb', 'Dia', 'BaD', 'Bbi', 'Dji', 'Bbb', 'Djb', 'tuk', 'wxg', 'yir', 'tuc', 'wxa',
289 'tuE', 'wxD', 'tuC', 'tuB', 'lmk', 'stg', 'nqk', 'lmc', 'sta', 'nqc', 'tva', 'stD', 'nqE',
290 'lmC', 'nqC', 'lmB', 'nqB', 'BCk', 'klg', 'Dak', 'BCc', 'str', 'bik', 'Dac', 'lna', 'klD',
291 'bic', 'nra', 'BCC', 'biE', 'DaC', 'BCB', 'DaB', 'BDg', 'klr', 'Dbg', 'BDa', 'bjg', 'Dba',
292 'BDD', 'bja', 'DbD', 'BDr', 'Dbr', 'bjr', 'xxc', 'yyq', 'xxE', 'yyn', 'xxC', 'xxB', 'ttc',
293 'wwq', 'vvc', 'xxq', 'wwn', 'vvE', 'xxn', 'vvC', 'ttB', 'vvB', 'llc', 'ssq', 'nnc', 'llE',
294 'ssn', 'rrc', 'nnE', 'ttn', 'rrE', 'vvn', 'llB', 'rrC', 'nnB', 'rrB', 'BBc', 'kkq', 'DDc',
295 'BBE', 'kkn', 'bbc', 'DDE', 'lln', 'jjc', 'bbE', 'nnn', 'BBB', 'jjE', 'rrn', 'DDB', 'jjC',
296 'BBq', 'DDq', 'BBn', 'bbq', 'DDn', 'jjq', 'bbn', 'jjn', 'xwo', 'yyf', 'xwm', 'xwl', 'tso',
297 'wwf', 'vto', 'xwv', 'vtm', 'tsl', 'vtl', 'lko', 'ssf', 'nlo', 'lkm', 'rno', 'nlm', 'lkl',
298 'rnm', 'nll', 'rnl', 'BAo', 'kkf', 'DBo', 'lkv', 'bDo', 'DBm', 'BAl', 'jbo', 'bDm', 'DBl',
299 'jbm', 'bDl', 'jbl', 'DBv', 'jbv', 'xwd', 'vsu', 'vst', 'nku', 'rlu', 'rlt', 'DAu', 'bBu',
300 'jDu', 'jDt', 'ApA', 'Aok', 'keg', 'Aoc', 'AoE', 'AoC', 'Aqs', 'Aqg', 'Aqa', 'AqD', 'Ari',
301 'Arb', 'kuk', 'kuc', 'sha', 'kuE', 'shD', 'kuC', 'kuB', 'Amk', 'kdg', 'Bqk', 'kvg', 'kda',
302 'Bqc', 'kva', 'BqE', 'kvD', 'BqC', 'AmB', 'BqB', 'Ang', 'kdr', 'Brg', 'kvr', 'Bra', 'AnD',
303 'BrD', 'Anr', 'Brr', 'sxc', 'sxE', 'sxC', 'sxB', 'ktc', 'lvc', 'sxq', 'sgn', 'lvE', 'sxn',
304 'lvC', 'ktB', 'lvB', 'Alc', 'Bnc', 'AlE', 'kcn', 'Drc', 'BnE', 'AlC', 'DrE', 'BnC', 'AlB',
305 'DrC', 'BnB', 'Alq', 'Bnq', 'Aln', 'Drq', 'Bnn', 'Drn', 'wyo', 'wym', 'wyl', 'swo', 'txo',
306 'wyv', 'txm', 'swl', 'txl', 'kso', 'sgf', 'lto', 'swv', 'nvo', 'ltm', 'ksl', 'nvm', 'ltl',
307 'nvl', 'Ako', 'kcf', 'Blo', 'ksv', 'Dno', 'Blm', 'Akl', 'bro', 'Dnm', 'Bll', 'brm', 'Dnl',
308 'Akv', 'Blv', 'Dnv', 'brv', 'yze', 'yzd', 'wye', 'xyu', 'wyd', 'xyt', 'swe', 'twu', 'swd',
309 'vxu', 'twt', 'vxt', 'kse', 'lsu', 'ksd', 'ntu', 'lst', 'rvu', 'ypk', 'zew', 'xdA', 'yos',
310 'zei', 'xck', 'yog', 'zeb', 'xcc', 'yoa', 'xcE', 'yoD', 'xcC', 'xhk', 'yqw', 'zfj', 'utA',
311 'xgs', 'yqi', 'usk', 'xgg', 'yqb', 'usc', 'xga', 'usE', 'xgD', 'usC', 'uxk', 'xiw', 'yrj',
312 'ptA', 'uws', 'xii', 'psk', 'uwg', 'xib', 'psc', 'uwa', 'psE', 'uwD', 'psC', 'pxk', 'uyw',
313 'xjj', 'ftA', 'pws', 'uyi', 'fsk', 'pwg', 'uyb', 'fsc', 'pwa', 'fsE', 'pwD', 'fxk', 'pyw',
314 'uzj', 'fws', 'pyi', 'fwg', 'pyb', 'fwa', 'fyw', 'pzj', 'fyi', 'fyb', 'xFA', 'yms', 'zdi',
315 'xEk', 'ymg', 'zdb', 'xEc', 'yma', 'xEE', 'ymD', 'xEC', 'xEB', 'uhA', 'xas', 'yni', 'ugk',
316 'xag', 'ynb', 'ugc', 'xaa', 'ugE', 'xaD', 'ugC', 'ugB', 'oxA', 'uis', 'xbi', 'owk', 'uig',
317 'xbb', 'owc', 'uia', 'owE', 'uiD', 'owC', 'owB', 'dxA', 'oys', 'uji', 'dwk', 'oyg', 'ujb',
318 'dwc', 'oya', 'dwE', 'oyD', 'dwC', 'dys', 'ozi', 'dyg', 'ozb', 'dya', 'dyD', 'dzi', 'dzb',
319 'xCk', 'ylg', 'zcr', 'xCc', 'yla', 'xCE', 'ylD', 'xCC', 'xCB', 'uak', 'xDg', 'ylr', 'uac',
320 'xDa', 'uaE', 'xDD', 'uaC', 'uaB', 'oik', 'ubg', 'xDr', 'oic', 'uba', 'oiE', 'ubD', 'oiC',
321 'oiB', 'cyk', 'ojg', 'ubr', 'cyc', 'oja', 'cyE', 'ojD', 'cyC', 'cyB', 'czg', 'ojr', 'cza',
322 'czD', 'czr', 'xBc', 'ykq', 'xBE', 'ykn', 'xBC', 'xBB', 'uDc', 'xBq', 'uDE', 'xBn', 'uDC',
323 'uDB', 'obc', 'uDq', 'obE', 'uDn', 'obC', 'obB', 'cjc', 'obq', 'cjE', 'obn', 'cjC', 'cjB',
324 'cjq', 'cjn', 'xAo', 'ykf', 'xAm', 'xAl', 'uBo', 'xAv', 'uBm', 'uBl', 'oDo', 'uBv', 'oDm',
325 'oDl', 'cbo', 'oDv', 'cbm', 'cbl', 'xAe', 'xAd', 'uAu', 'uAt', 'oBu', 'oBt', 'wpA', 'yes',
326 'zFi', 'wok', 'yeg', 'zFb', 'woc', 'yea', 'woE', 'yeD', 'woC', 'woB', 'thA', 'wqs', 'yfi',
327 'tgk', 'wqg', 'yfb', 'tgc', 'wqa', 'tgE', 'wqD', 'tgC', 'tgB', 'mxA', 'tis', 'wri', 'mwk',
328 'tig', 'wrb', 'mwc', 'tia', 'mwE', 'tiD', 'mwC', 'mwB', 'FxA', 'mys', 'tji', 'Fwk', 'myg',
329 'tjb', 'Fwc', 'mya', 'FwE', 'myD', 'FwC', 'Fys', 'mzi', 'Fyg', 'mzb', 'Fya', 'FyD', 'Fzi',
330 'Fzb', 'yuk', 'zhg', 'hjs', 'yuc', 'zha', 'hbw', 'yuE', 'zhD', 'hDy', 'yuC', 'yuB', 'wmk',
331 'ydg', 'zEr', 'xqk', 'wmc', 'zhr', 'xqc', 'yva', 'ydD', 'xqE', 'wmC', 'xqC', 'wmB', 'xqB',
332 'tak', 'wng', 'ydr', 'vik', 'tac', 'wna', 'vic', 'xra', 'wnD', 'viE', 'taC', 'viC', 'taB',
333 'viB', 'mik', 'tbg', 'wnr', 'qyk', 'mic', 'tba', 'qyc', 'vja', 'tbD', 'qyE', 'miC', 'qyC',
334 'miB', 'qyB', 'Eyk', 'mjg', 'tbr', 'hyk', 'Eyc', 'mja', 'hyc', 'qza', 'mjD', 'hyE', 'EyC',
335 'hyC', 'EyB', 'Ezg', 'mjr', 'hzg', 'Eza', 'hza', 'EzD', 'hzD', 'Ezr', 'ytc', 'zgq', 'grw',
336 'ytE', 'zgn', 'gny', 'ytC', 'glz', 'ytB', 'wlc', 'ycq', 'xnc', 'wlE', 'ycn', 'xnE', 'ytn',
337 'xnC', 'wlB', 'xnB', 'tDc', 'wlq', 'vbc', 'tDE', 'wln', 'vbE', 'xnn', 'vbC', 'tDB', 'vbB',
338 'mbc', 'tDq', 'qjc', 'mbE', 'tDn', 'qjE', 'vbn', 'qjC', 'mbB', 'qjB', 'Ejc', 'mbq', 'gzc',
339 'EjE', 'mbn', 'gzE', 'qjn', 'gzC', 'EjB', 'gzB', 'Ejq', 'gzq', 'Ejn', 'gzn', 'yso', 'zgf',
340 'gfy', 'ysm', 'gdz', 'ysl', 'wko', 'ycf', 'xlo', 'ysv', 'xlm', 'wkl', 'xll', 'tBo', 'wkv',
341 'vDo', 'tBm', 'vDm', 'tBl', 'vDl', 'mDo', 'tBv', 'qbo', 'vDv', 'qbm', 'mDl', 'qbl', 'Ebo',
342 'mDv', 'gjo', 'Ebm', 'gjm', 'Ebl', 'gjl', 'Ebv', 'gjv', 'yse', 'gFz', 'ysd', 'wke', 'xku',
343 'wkd', 'xkt', 'tAu', 'vBu', 'tAt', 'vBt', 'mBu', 'qDu', 'mBt', 'qDt', 'EDu', 'gbu', 'EDt',
344 'gbt', 'ysF', 'wkF', 'xkh', 'tAh', 'vAx', 'mAx', 'qBx', 'wek', 'yFg', 'zCr', 'wec', 'yFa',
345 'weE', 'yFD', 'weC', 'weB', 'sqk', 'wfg', 'yFr', 'sqc', 'wfa', 'sqE', 'wfD', 'sqC', 'sqB',
346 'lik', 'srg', 'wfr', 'lic', 'sra', 'liE', 'srD', 'liC', 'liB', 'Cyk', 'ljg', 'srr', 'Cyc',
347 'lja', 'CyE', 'ljD', 'CyC', 'CyB', 'Czg', 'ljr', 'Cza', 'CzD', 'Czr', 'yhc', 'zaq', 'arw',
348 'yhE', 'zan', 'any', 'yhC', 'alz', 'yhB', 'wdc', 'yEq', 'wvc', 'wdE', 'yEn', 'wvE', 'yhn',
349 'wvC', 'wdB', 'wvB', 'snc', 'wdq', 'trc', 'snE', 'wdn', 'trE', 'wvn', 'trC', 'snB', 'trB',
350 'lbc', 'snq', 'njc', 'lbE', 'snn', 'njE', 'trn', 'njC', 'lbB', 'njB', 'Cjc', 'lbq', 'azc',
351 'CjE', 'lbn', 'azE', 'njn', 'azC', 'CjB', 'azB', 'Cjq', 'azq', 'Cjn', 'azn', 'zio', 'irs',
352 'rfy', 'zim', 'inw', 'rdz', 'zil', 'ily', 'ikz', 'ygo', 'zaf', 'afy', 'yxo', 'ziv', 'ivy',
353 'adz', 'yxm', 'ygl', 'itz', 'yxl', 'wco', 'yEf', 'wto', 'wcm', 'xvo', 'yxv', 'wcl', 'xvm',
354 'wtl', 'xvl', 'slo', 'wcv', 'tno', 'slm', 'vro', 'tnm', 'sll', 'vrm', 'tnl', 'vrl', 'lDo',
355 'slv', 'nbo', 'lDm', 'rjo', 'nbm', 'lDl', 'rjm', 'nbl', 'rjl', 'Cbo', 'lDv', 'ajo', 'Cbm',
356 'izo', 'ajm', 'Cbl', 'izm', 'ajl', 'izl', 'Cbv', 'ajv', 'zie', 'ifw', 'rFz', 'zid', 'idy',
357 'icz', 'yge', 'aFz', 'ywu', 'ygd', 'ihz', 'ywt', 'wce', 'wsu', 'wcd', 'xtu', 'wst', 'xtt',
358 'sku', 'tlu', 'skt', 'vnu', 'tlt', 'vnt', 'lBu', 'nDu', 'lBt', 'rbu', 'nDt', 'rbt', 'CDu',
359 'abu', 'CDt', 'iju', 'abt', 'ijt', 'ziF', 'iFy', 'iEz', 'ygF', 'ywh', 'wcF', 'wsh', 'xsx',
360 'skh', 'tkx', 'vlx', 'lAx', 'nBx', 'rDx', 'CBx', 'aDx', 'ibx', 'iCz', 'wFc', 'yCq', 'wFE',
361 'yCn', 'wFC', 'wFB', 'sfc', 'wFq', 'sfE', 'wFn', 'sfC', 'sfB', 'krc', 'sfq', 'krE', 'sfn',
362 'krC', 'krB', 'Bjc', 'krq', 'BjE', 'krn', 'BjC', 'BjB', 'Bjq', 'Bjn', 'yao', 'zDf', 'Dfy',
363 'yam', 'Ddz', 'yal', 'wEo', 'yCf', 'who', 'wEm', 'whm', 'wEl', 'whl', 'sdo', 'wEv', 'svo',
364 'sdm', 'svm', 'sdl', 'svl', 'kno', 'sdv', 'lro', 'knm', 'lrm', 'knl', 'lrl', 'Bbo', 'knv',
365 'Djo', 'Bbm', 'Djm', 'Bbl', 'Djl', 'Bbv', 'Djv', 'zbe', 'bfw', 'npz', 'zbd', 'bdy', 'bcz',
366 'yae', 'DFz', 'yiu', 'yad', 'bhz', 'yit', 'wEe', 'wgu', 'wEd', 'wxu', 'wgt', 'wxt', 'scu',
367 'stu', 'sct', 'tvu', 'stt', 'tvt', 'klu', 'lnu', 'klt', 'nru', 'lnt', 'nrt', 'BDu', 'Dbu',
368 'BDt', 'bju', 'Dbt', 'bjt', 'jfs', 'rpy', 'jdw', 'roz', 'jcy', 'jcj', 'zbF', 'bFy', 'zjh',
369 'jhy', 'bEz', 'jgz', 'yaF', 'yih', 'yyx', 'wEF', 'wgh', 'wwx', 'xxx', 'sch', 'ssx', 'ttx',
370 'vvx', 'kkx', 'llx', 'nnx', 'rrx', 'BBx', 'DDx', 'bbx', 'jFw', 'rmz', 'jEy', 'jEj', 'bCz',
371 'jaz', 'jCy', 'jCj', 'jBj', 'wCo', 'wCm', 'wCl', 'sFo', 'wCv', 'sFm', 'sFl', 'kfo', 'sFv',
372 'kfm', 'kfl', 'Aro', 'kfv', 'Arm', 'Arl', 'Arv', 'yDe', 'Bpz', 'yDd', 'wCe', 'wau', 'wCd',
373 'wat', 'sEu', 'shu', 'sEt', 'sht', 'kdu', 'kvu', 'kdt', 'kvt', 'Anu', 'Bru', 'Ant', 'Brt',
374 'zDp', 'Dpy', 'Doz', 'yDF', 'ybh', 'wCF', 'wah', 'wix', 'sEh', 'sgx', 'sxx', 'kcx', 'ktx',
375 'lvx', 'Alx', 'Bnx', 'Drx', 'bpw', 'nuz', 'boy', 'boj', 'Dmz', 'bqz', 'jps', 'ruy', 'jow',
376 'ruj', 'joi', 'job', 'bmy', 'jqy', 'bmj', 'jqj', 'jmw', 'rtj', 'jmi', 'jmb', 'blj', 'jnj',
377 'jli', 'jlb', 'jkr', 'sCu', 'sCt', 'kFu', 'kFt', 'Afu', 'Aft', 'wDh', 'sCh', 'sax', 'kEx',
378 'khx', 'Adx', 'Avx', 'Buz', 'Duy', 'Duj', 'buw', 'nxj', 'bui', 'bub', 'Dtj', 'bvj', 'jus',
379 'rxi', 'jug', 'rxb', 'jua', 'juD', 'bti', 'jvi', 'btb', 'jvb', 'jtg', 'rwr', 'jta', 'jtD',
380 'bsr', 'jtr', 'jsq', 'jsn', 'Bxj', 'Dxi', 'Dxb', 'bxg', 'nyr', 'bxa', 'bxD', 'Dwr', 'bxr',
381 'bwq', 'bwn', 'pjk', 'urw', 'ejA', 'pbs', 'uny', 'ebk', 'pDw', 'ulz', 'eDs', 'pBy', 'eBw',
382 'zfc', 'fjk', 'prw', 'zfE', 'fbs', 'pny', 'zfC', 'fDw', 'plz', 'zfB', 'fBy', 'yrc', 'zfq',
383 'frw', 'yrE', 'zfn', 'fny', 'yrC', 'flz', 'yrB', 'xjc', 'yrq', 'xjE', 'yrn', 'xjC', 'xjB',
384 'uzc', 'xjq', 'uzE', 'xjn', 'uzC', 'uzB', 'pzc', 'uzq', 'pzE', 'uzn', 'pzC', 'djA', 'ors',
385 'ufy', 'dbk', 'onw', 'udz', 'dDs', 'oly', 'dBw', 'okz', 'dAy', 'zdo', 'drs', 'ovy', 'zdm',
386 'dnw', 'otz', 'zdl', 'dly', 'dkz', 'yno', 'zdv', 'dvy', 'ynm', 'dtz', 'ynl', 'xbo', 'ynv',
387 'xbm', 'xbl', 'ujo', 'xbv', 'ujm', 'ujl', 'ozo', 'ujv', 'ozm', 'ozl', 'crk', 'ofw', 'uFz',
388 'cns', 'ody', 'clw', 'ocz', 'cky', 'ckj', 'zcu', 'cvw', 'ohz', 'zct', 'cty', 'csz', 'ylu',
389 'cxz', 'ylt', 'xDu', 'xDt', 'ubu', 'ubt', 'oju', 'ojt', 'cfs', 'oFy', 'cdw', 'oEz', 'ccy',
390 'ccj', 'zch', 'chy', 'cgz', 'ykx', 'xBx', 'uDx', 'cFw', 'oCz', 'cEy', 'cEj', 'caz', 'cCy',
391 'cCj', 'FjA', 'mrs', 'tfy', 'Fbk', 'mnw', 'tdz', 'FDs', 'mly', 'FBw', 'mkz', 'FAy', 'zFo',
392 'Frs', 'mvy', 'zFm', 'Fnw', 'mtz', 'zFl', 'Fly', 'Fkz', 'yfo', 'zFv', 'Fvy', 'yfm', 'Ftz',
393 'yfl', 'wro', 'yfv', 'wrm', 'wrl', 'tjo', 'wrv', 'tjm', 'tjl', 'mzo', 'tjv', 'mzm', 'mzl',
394 'qrk', 'vfw', 'xpz', 'hbA', 'qns', 'vdy', 'hDk', 'qlw', 'vcz', 'hBs', 'qky', 'hAw', 'qkj',
395 'hAi', 'Erk', 'mfw', 'tFz', 'hrk', 'Ens', 'mdy', 'hns', 'qty', 'mcz', 'hlw', 'Eky', 'hky',
396 'Ekj', 'hkj', 'zEu', 'Evw', 'mhz', 'zhu', 'zEt', 'hvw', 'Ety', 'zht', 'hty', 'Esz', 'hsz',
397 'ydu', 'Exz', 'yvu', 'ydt', 'hxz', 'yvt', 'wnu', 'xru', 'wnt', 'xrt', 'tbu', 'vju', 'tbt',
398 'vjt', 'mju', 'mjt', 'grA', 'qfs', 'vFy', 'gnk', 'qdw', 'vEz', 'gls', 'qcy', 'gkw', 'qcj',
399 'gki', 'gkb', 'Efs', 'mFy', 'gvs', 'Edw', 'mEz', 'gtw', 'qgz', 'gsy', 'Ecj', 'gsj', 'zEh',
400 'Ehy', 'zgx', 'gxy', 'Egz', 'gwz', 'ycx', 'ytx', 'wlx', 'xnx', 'tDx', 'vbx', 'mbx', 'gfk',
401 'qFw', 'vCz', 'gds', 'qEy', 'gcw', 'qEj', 'gci', 'gcb', 'EFw', 'mCz', 'ghw', 'EEy', 'ggy',
402 'EEj', 'ggj', 'Eaz', 'giz', 'gFs', 'qCy', 'gEw', 'qCj', 'gEi', 'gEb', 'ECy', 'gay', 'ECj',
403 'gaj', 'gCw', 'qBj', 'gCi', 'gCb', 'EBj', 'gDj', 'gBi', 'gBb', 'Crk', 'lfw', 'spz', 'Cns',
404 'ldy', 'Clw', 'lcz', 'Cky', 'Ckj', 'zCu', 'Cvw', 'lhz', 'zCt', 'Cty', 'Csz', 'yFu', 'Cxz',
405 'yFt', 'wfu', 'wft', 'sru', 'srt', 'lju', 'ljt', 'arA', 'nfs', 'tpy', 'ank', 'ndw', 'toz',
406 'als', 'ncy', 'akw', 'ncj', 'aki', 'akb', 'Cfs', 'lFy', 'avs', 'Cdw', 'lEz', 'atw', 'ngz',
407 'asy', 'Ccj', 'asj', 'zCh', 'Chy', 'zax', 'axy', 'Cgz', 'awz', 'yEx', 'yhx', 'wdx', 'wvx',
408 'snx', 'trx', 'lbx', 'rfk', 'vpw', 'xuz', 'inA', 'rds', 'voy', 'ilk', 'rcw', 'voj', 'iks',
409 'rci', 'ikg', 'rcb', 'ika', 'afk', 'nFw', 'tmz', 'ivk', 'ads', 'nEy', 'its', 'rgy', 'nEj',
410 'isw', 'aci', 'isi', 'acb', 'isb', 'CFw', 'lCz', 'ahw', 'CEy', 'ixw', 'agy', 'CEj', 'iwy',
411 'agj', 'iwj', 'Caz', 'aiz', 'iyz', 'ifA', 'rFs', 'vmy', 'idk', 'rEw', 'vmj', 'ics', 'rEi',
412 'icg', 'rEb', 'ica', 'icD', 'aFs', 'nCy', 'ihs', 'aEw', 'nCj', 'igw', 'raj', 'igi', 'aEb',
413 'igb', 'CCy', 'aay', 'CCj', 'iiy', 'aaj', 'iij', 'iFk', 'rCw', 'vlj', 'iEs', 'rCi', 'iEg',
414 'rCb', 'iEa', 'iED', 'aCw', 'nBj', 'iaw', 'aCi', 'iai', 'aCb', 'iab', 'CBj', 'aDj', 'ibj',
415 'iCs', 'rBi', 'iCg', 'rBb', 'iCa', 'iCD', 'aBi', 'iDi', 'aBb', 'iDb', 'iBg', 'rAr', 'iBa',
416 'iBD', 'aAr', 'iBr', 'iAq', 'iAn', 'Bfs', 'kpy', 'Bdw', 'koz', 'Bcy', 'Bcj', 'Bhy', 'Bgz',
417 'yCx', 'wFx', 'sfx', 'krx', 'Dfk', 'lpw', 'suz', 'Dds', 'loy', 'Dcw', 'loj', 'Dci', 'Dcb',
418 'BFw', 'kmz', 'Dhw', 'BEy', 'Dgy', 'BEj', 'Dgj', 'Baz', 'Diz', 'bfA', 'nps', 'tuy', 'bdk',
419 'now', 'tuj', 'bcs', 'noi', 'bcg', 'nob', 'bca', 'bcD', 'DFs', 'lmy', 'bhs', 'DEw', 'lmj',
420 'bgw', 'DEi', 'bgi', 'DEb', 'bgb', 'BCy', 'Day', 'BCj', 'biy', 'Daj', 'bij', 'rpk', 'vuw',
421 'xxj', 'jdA', 'ros', 'vui', 'jck', 'rog', 'vub', 'jcc', 'roa', 'jcE', 'roD', 'jcC', 'bFk',
422 'nmw', 'ttj', 'jhk', 'bEs', 'nmi', 'jgs', 'rqi', 'nmb', 'jgg', 'bEa', 'jga', 'bED', 'jgD',
423 'DCw', 'llj', 'baw', 'DCi', 'jiw', 'bai', 'DCb', 'jii', 'bab', 'jib', 'BBj', 'DDj', 'bbj',
424 'jjj', 'jFA', 'rms', 'vti', 'jEk', 'rmg', 'vtb', 'jEc', 'rma', 'jEE', 'rmD', 'jEC', 'jEB',
425 'bCs', 'nli', 'jas', 'bCg', 'nlb', 'jag', 'rnb', 'jaa', 'bCD', 'jaD', 'DBi', 'bDi', 'DBb',
426 'jbi', 'bDb', 'jbb', 'jCk', 'rlg', 'vsr', 'jCc', 'rla', 'jCE', 'rlD', 'jCC', 'jCB', 'bBg',
427 'nkr', 'jDg', 'bBa', 'jDa', 'bBD', 'jDD', 'DAr', 'bBr', 'jDr', 'jBc', 'rkq', 'jBE', 'rkn',
428 'jBC', 'jBB', 'bAq', 'jBq', 'bAn', 'jBn', 'jAo', 'rkf', 'jAm', 'jAl', 'bAf', 'jAv', 'Apw',
429 'kez', 'Aoy', 'Aoj', 'Aqz', 'Bps', 'kuy', 'Bow', 'kuj', 'Boi', 'Bob', 'Amy', 'Bqy', 'Amj',
430 'Bqj', 'Dpk', 'luw', 'sxj', 'Dos', 'lui', 'Dog', 'lub', 'Doa', 'DoD', 'Bmw', 'ktj', 'Dqw',
431 'Bmi', 'Dqi', 'Bmb', 'Dqb', 'Alj', 'Bnj', 'Drj', 'bpA', 'nus', 'txi', 'bok', 'nug', 'txb',
432 'boc', 'nua', 'boE', 'nuD', 'boC', 'boB', 'Dms', 'lti', 'bqs', 'Dmg', 'ltb', 'bqg', 'nvb',
433 'bqa', 'DmD', 'bqD', 'Bli', 'Dni', 'Blb', 'bri', 'Dnb', 'brb', 'ruk', 'vxg', 'xyr', 'ruc',
434 'vxa', 'ruE', 'vxD', 'ruC', 'ruB', 'bmk', 'ntg', 'twr', 'jqk', 'bmc', 'nta', 'jqc', 'rva',
435 'ntD', 'jqE', 'bmC', 'jqC', 'bmB', 'jqB', 'Dlg', 'lsr', 'bng', 'Dla', 'jrg', 'bna', 'DlD',
436 'jra', 'bnD', 'jrD', 'Bkr', 'Dlr', 'bnr', 'jrr', 'rtc', 'vwq', 'rtE', 'vwn', 'rtC', 'rtB',
437 'blc', 'nsq', 'jnc', 'blE', 'nsn', 'jnE', 'rtn', 'jnC', 'blB', 'jnB', 'Dkq', 'blq', 'Dkn',
438 'jnq', 'bln', 'jnn', 'rso', 'vwf', 'rsm', 'rsl', 'bko', 'nsf', 'jlo', 'bkm', 'jlm', 'bkl',
439 'jll', 'Dkf', 'bkv', 'jlv', 'rse', 'rsd', 'bke', 'jku', 'bkd', 'jkt', 'Aey', 'Aej', 'Auw',
440 'khj', 'Aui', 'Aub', 'Adj', 'Avj', 'Bus', 'kxi', 'Bug', 'kxb', 'Bua', 'BuD', 'Ati', 'Bvi',
441 'Atb', 'Bvb', 'Duk', 'lxg', 'syr', 'Duc', 'lxa', 'DuE', 'lxD', 'DuC', 'DuB', 'Btg', 'kwr',
442 'Dvg', 'lxr', 'Dva', 'BtD', 'DvD', 'Asr', 'Btr', 'Dvr', 'nxc', 'tyq', 'nxE', 'tyn', 'nxC',
443 'nxB', 'Dtc', 'lwq', 'bvc', 'nxq', 'lwn', 'bvE', 'DtC', 'bvC', 'DtB', 'bvB', 'Bsq', 'Dtq',
444 'Bsn', 'bvq', 'Dtn', 'bvn', 'vyo', 'xzf', 'vym', 'vyl', 'nwo', 'tyf', 'rxo', 'nwm', 'rxm',
445 'nwl', 'rxl', 'Dso', 'lwf', 'bto', 'Dsm', 'jvo', 'btm', 'Dsl', 'jvm', 'btl', 'jvl', 'Bsf',
446 'Dsv', 'btv', 'jvv', 'vye', 'vyd', 'nwe', 'rwu', 'nwd', 'rwt', 'Dse', 'bsu', 'Dsd', 'jtu',
447 'bst', 'jtt', 'vyF', 'nwF', 'rwh', 'DsF', 'bsh', 'jsx', 'Ahi', 'Ahb', 'Axg', 'kir', 'Axa',
448 'AxD', 'Agr', 'Axr', 'Bxc', 'kyq', 'BxE', 'kyn', 'BxC', 'BxB', 'Awq', 'Bxq', 'Awn', 'Bxn',
449 'lyo', 'szf', 'lym', 'lyl', 'Bwo', 'kyf', 'Dxo', 'lyv', 'Dxm', 'Bwl', 'Dxl', 'Awf', 'Bwv',
450 'Dxv', 'tze', 'tzd', 'lye', 'nyu', 'lyd', 'nyt', 'Bwe', 'Dwu', 'Bwd', 'bxu', 'Dwt', 'bxt',
451 'tzF', 'lyF', 'nyh', 'BwF', 'Dwh', 'bwx', 'Aiq', 'Ain', 'Ayo', 'kjf', 'Aym', 'Ayl', 'Aif',
452 'Ayv', 'kze', 'kzd', 'Aye', 'Byu', 'Ayd', 'Byt', 'szp'
453 );
454
455 {
456 Three figure numbers in comments give the location of command equivalents in the
457 original Visual Basic source code file pdf417.frm
458 this code retains some original (French) procedure and variable names to ease conversion }
459
460 { text mode processing tables }
461 asciix: array[0..94] of Integer = (
462 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4,
463 4, 4, 12, 8, 8, 4, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
464 1, 1, 1, 1, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
465 2, 2, 2, 2, 8, 8, 8, 8
466 );
467
468 asciiy: array[0..94] of Integer = (
469 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3,
470 4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
471 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4, 5, 6, 24, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
472 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 21, 27, 9
473 );
474
475 { Automatic sizing table }
476 MicroAutosize : array[0..55] of Integer = (
477 4, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19, 20, 24, 29, 30, 33, 34, 37, 39, 46, 54, 58, 70, 72, 82, 90, 108, 126,
478 1, 14, 2, 7, 3, 25, 8, 16, 5, 17, 9, 6, 10, 11, 28, 12, 19, 13, 29, 20, 30, 21, 22, 31, 23, 32, 33, 34
479 );
480
481type
482 TGlobalList = array[0..1] of array[0..999] of Integer;
483
484{ 866 }
485
486function GetMode(code: Char): Integer;
487begin
488 if (code in [#9, #10, #13]) or ((code >= ' ') and (code <= '~')) then
489 Result := TEX
490 else
491 if (code >= '0') and (code <= '9') then
492 Result := NUM
493 else
494 Result := BYT;
495end;
496
497{ 844 }
498procedure ReGroup(var index_list: Integer; var list: TGlobalList);
499var
500 i, j : Integer;
501begin
502 { bring together same type blocks }
503 if (index_list > 1) then
504 begin
505 i := 1;
506 while(i < index_list) do
507 begin
508 if (list[1, i - 1] = list[1, i]) then
509 begin
510 { bring together }
511 list[0, i - 1] := list[0, i - 1] + list[0, i];
512 j := i + 1;
513
514 { decreace the list }
515 while (j < index_list) do
516 begin
517 list[0, j - 1] := list[0, j];
518 list[1, j - 1] := list[1, j];
519 Inc(j);
520 end;
521 dec(index_list);
522 dec(i);
523 end;
524 inc(i);
525 end;
526 end;
527 { 865 }
528end;
529
530
531{ 478 }
532procedure pdfsmooth(var index_list: Integer; var list: TGlobalList);
533var
534 i, crnt, last, next, len: Integer;
535begin
536 for i := 0 to index_list - 1 do
537 begin
538 crnt := list[1, i];
539 len := list[0, i];
540 if (i <> 0) then last := list[1, i - 1] else last := _FALSE;
541 if (i <> index_list - 1) then next := list[1, i + 1] else next := _FALSE;
542
543 if (crnt = NUM) then
544 begin
545 if (i = 0) then
546 begin { first block }
547 if (index_list > 1) then
548 begin { and there are others }
549 if ((next = TEX) and (len < 8)) then list[1, i] := TEX;
550 if ((next = BYT) and (len = 1)) then list[1, i] := BYT;
551 end;
552 end
553 else
554 begin
555 if (i = index_list - 1) then
556 begin { last block }
557 if ((last = TEX) and (len < 7)) then list[1, i] := TEX;
558 if ((last = BYT) and (len = 1)) then list[1, i] := BYT;
559 end
560 else
561 begin { not first or last block }
562 if (((last = BYT) and (next = BYT)) and (len < 4)) then list[1, i] := BYT;
563 if (((last = BYT) and (next = TEX)) and (len < 4)) then list[1, i] := TEX;
564 if (((last = TEX) and (next = BYT)) and (len < 5)) then list[1, i] := TEX;
565 if (((last = TEX) and (next = TEX)) and (len < 8)) then list[1, i] := TEX;
566 end;
567 end;
568 end;
569 end;
570 ReGroup(index_list, list);
571
572 { 520 }
573 for i := 0 to index_list - 1 do
574 begin
575 crnt := list[1, i];
576 len := list[0, i];
577 if (i <> 0) then last := list[1, i - 1] else last := _FALSE;
578 if (i <> index_list - 1) then next := list[1, i + 1] else next := _FALSE;
579
580 if ((crnt = TEX) and (i > 0)) then
581 begin { not the first }
582 if (i = index_list - 1) then
583 begin { the last one }
584 if ((last = BYT) and (len = 1)) then list[1, i] := BYT;
585 end
586 else
587 begin { not the last one }
588 if (((last = BYT) and (next = BYT)) and (len < 5)) then
589 list[1, i] := BYT;
590 if ((((last = BYT) and (next <> BYT)) or ((last <> BYT) and (next = BYT))) and (len < 3)) then
591 list[1, i] := BYT;
592 end;
593 end;
594 end;
595 { 540 }
596 ReGroup(index_list, list);
597end;
598
599{ 547 }
600procedure textprocess(var chainemc : TIntegerDynArray; var mc_length: Integer;
601 ASource: PChar; start, _length, {%H-}block: Integer);
602var
603 j, indexlistet, curtable : Integer;
604 listet : array[0..1] of array[0..4999] of Integer;
605 chainet: array[0..4999] of Integer;
606 wnet : Integer;
607 codeascii : Char;
608 flag : Integer;
609 newtable : Integer;
610 cw_number : Integer;
611begin
612 //codeascii := #0;
613 wnet := 0;
614
615 for j := 0 to 999 do
616 listet[0][j] := 0;
617
618 { listet will contain the table numbers and the value of each characters }
619 for indexlistet := 0 to _length - 1 do
620 begin
621 codeascii := ASource[start + indexlistet];
622 case codeascii of
623 #9:
624 begin
625 listet[0][indexlistet] := 12;
626 listet[1][indexlistet] := 12;
627 end;
628 #10:
629 begin
630 listet[0][indexlistet] := 8;
631 listet[1][indexlistet] := 15;
632 end;
633 #13:
634 begin
635 listet[0][indexlistet] := 12;
636 listet[1][indexlistet] := 11;
637 end;
638 else
639 begin
640 listet[0][indexlistet] := asciix[Ord(codeascii) - 32];
641 listet[1][indexlistet] := asciiy[Ord(codeascii) - 32];
642 end;
643 end;
644 end;
645
646 { 570 }
647 curtable := 1; { default table }
648 for j := 0 to _length - 1 do
649 begin
650 if (listet[0][j] and curtable) <> 0 then
651 begin { The character is in the current table }
652 chainet[wnet] := listet[1][j];
653 Inc(wnet);
654 end
655 else
656 begin { Obliged to change table }
657 flag := _FALSE; { True if we change table for only one character }
658 if (j = (_length - 1)) then
659 flag := _TRUE
660 else
661 if not ((listet[0][j] and listet[0][j + 1]) <> 0) then flag := _TRUE;
662
663 if (flag <> 0) then
664 begin { we change only one character - look for temporary switch }
665 if (((listet[0][j] and 1) <> 0) and (curtable = 2)) then
666 begin { T_UPP }
667 chainet[wnet] := 27;
668 chainet[wnet + 1] := listet[1][j];
669 Inc(wnet, 2);
670 end;
671 if (listet[0][j] and 8) <> 0 then
672 begin { T_PUN }
673 chainet[wnet] := 29;
674 chainet[wnet + 1] := listet[1][j];
675 Inc(wnet, 2);
676 end;
677 if (not ((((listet[0][j] and 1) <> 0) and (curtable = 2)) or ((listet[0][j] and 8) <> 0))) then
678 begin
679 { No temporary switch available }
680 flag := _FALSE;
681 end;
682 end;
683
684 { 599 }
685 if (not (flag <> 0)) then
686 begin
687 if (j = (_length - 1)) then
688 newtable := listet[0][j]
689 else
690 begin
691 if (not ((listet[0][j] and listet[0][j + 1]) <> 0)) then
692 newtable := listet[0][j]
693 else
694 newtable := listet[0][j] and listet[0][j + 1];
695 end;
696
697 { Maintain the first if several tables are possible }
698 case newtable of
699 3,
700 5,
701 7,
702 9,
703 11,
704 13,
705 15:
706 newtable := 1;
707 6,
708 10,
709 14:
710 newtable := 2;
711 12:
712 newtable := 4;
713 end;
714
715 { 619 - select the switch }
716 case curtable of
717 1:
718 case newtable of
719 2: begin chainet[wnet] := 27; Inc(wnet); end;
720 4: begin chainet[wnet] := 28; Inc(wnet); end;
721 8: begin chainet[wnet] := 28; Inc(wnet); chainet[wnet] := 25; Inc(wnet); end;
722 end;
723 2:
724 case newtable of
725 1: begin chainet[wnet] := 28; Inc(wnet); chainet[wnet] := 28; Inc(wnet); end;
726 4: begin chainet[wnet] := 28; Inc(wnet); end;
727 8: begin chainet[wnet] := 28; Inc(wnet); chainet[wnet] := 25; Inc(wnet); end;
728 end;
729 4:
730 case newtable of
731 1: begin chainet[wnet] := 28; Inc(wnet); end;
732 2: begin chainet[wnet] := 27; Inc(wnet); end;
733 8: begin chainet[wnet] := 25; Inc(wnet); end;
734 end;
735 8:
736 case newtable of
737 1: begin chainet[wnet] := 29; Inc(wnet); end;
738 2: begin chainet[wnet] := 29; Inc(wnet); chainet[wnet] := 27; Inc(wnet); end;
739 4: begin chainet[wnet] := 29; Inc(wnet); chainet[wnet] := 28; Inc(wnet); end;
740 end;
741 end;
742 curtable := newtable;
743 { 659 - at last we add the character }
744 chainet[wnet] := listet[1][j];
745 Inc(wnet);
746 end;
747 end;
748 end;
749
750 { 663 }
751 if (wnet and 1) <> 0 then
752 begin
753 chainet[wnet] := 29;
754 Inc(wnet);
755 end;
756 { Now translate the string chainet into codewords }
757 chainemc[mc_length] := 900;
758 mc_length := mc_length + 1;
759
760 j := 0;
761 while j < wnet do
762 begin
763 cw_number := (30 * chainet[j]) + chainet[j + 1];
764 chainemc[mc_length] := cw_number;
765 mc_length := mc_length + 1;
766 Inc(j, 2);
767 end;
768end;
769
770{ 671 }
771procedure byteprocess(var chainemc: TIntegerDynArray; var mc_length: Integer;
772 ASource: PByte; start, _length, {%H-}block: Integer);
773var
774 len : Integer;
775 chunkLen : UInt64;
776 mantisa : UInt64;
777 total : UInt64;
778begin
779 len := 0;
780 //chunkLen := 0;
781 //mantisa := 0;
782 //total := 0;
783
784 if (_length = 1) then
785 begin
786 chainemc[mc_length] := 913;
787 Inc(mc_length);
788 chainemc[mc_length] := ASource[start];
789 Inc(mc_length);
790 end
791 else
792 begin
793 { select the switch for multiple of 6 bytes }
794 if (_length mod 6 = 0) then
795 begin
796 chainemc[mc_length] := 924;
797 Inc(mc_length);
798 end
799 else
800 begin
801 chainemc[mc_length] := 901;
802 Inc(mc_length);
803 end;
804
805 while (len < _length) do
806 begin
807 chunkLen := _length - len;
808 if (6 <= chunkLen) then { Take groups of 6 }
809 begin
810 chunkLen := 6;
811 Inc(len, chunkLen);
812 total := 0;
813
814 while (chunkLen > 0) do
815 begin
816 Dec(chunkLen);
817 mantisa := ASource[start];
818 Inc(start);
819 total := total or (mantisa shl UInt64(chunkLen * 8));
820 end;
821
822 chunkLen := 5;
823
824 while (chunkLen > 0) do
825 begin
826 Dec(chunkLen);
827 chainemc[mc_length + Int64(chunkLen)] := Integer(total mod 900);
828 total := total div 900;
829 end;
830 Inc(mc_length, 5);
831 end
832 else { If it remain a group of less than 6 bytes }
833 begin
834 Inc(len, chunkLen);
835 while (chunkLen > 0) do
836 begin
837 Dec(chunkLen);
838 chainemc[mc_length] := ASource[start];
839 Inc(mc_length);
840 Inc(start);
841 end;
842 end;
843 end;
844 end;
845end;
846
847{ 712 }
848procedure numbprocess(var chainemc: TIntegerDynArray; var mc_length: Integer;
849 ASource: PChar; start, _length, {%H-}block: Integer);
850var
851 j, loop, len, dum_length, diviseur, nombre : Integer;
852 dummy : array[0..99] of Integer;
853 chainemod: TCharDynArray = nil;
854 chainemult: TCharDynArray = nil;
855 temp: Char;
856 P: PChar;
857begin
858 SetLength(chainemod, 50);
859 SetLength(chainemult, 100);
860 strcpy(chainemod, '');
861 for loop := 0 to 50 do
862 dummy[loop] := 0;
863
864 chainemc[mc_length] := 902;
865 mc_length := mc_length + 1;
866
867 j := 0;
868 while(j < _length) do
869 begin
870 dum_length := 0;
871 strcpy(chainemod, '');
872 len := _length - j;
873 if (len > 44) then len := 44;
874 concat(chainemod, '1');
875 for loop := 1 to len do
876 begin
877 P := @ASource[start + loop + j - 1];
878 chainemod[loop] := P^;
879 end;
880 chainemod[len + 1] := #0;
881
882 repeat
883 diviseur := 900;
884
885 { 877 - gosub Modulo }
886 strcpy(chainemult, '');
887 nombre := 0;
888 while (strlen(chainemod) <> 0) do
889 begin
890 nombre := nombre * 10;
891 Inc(nombre, ctoi(chainemod[0]));
892 for loop := 0 to strlen(chainemod) - 1 do
893 chainemod[loop] := chainemod[loop + 1];
894
895 if (nombre < diviseur) then
896 begin
897 if (strlen(chainemult) <> 0) then concat(chainemult, '0');
898 end
899 else
900 begin
901 temp := Chr((nombre div diviseur) + Ord('0'));
902 chainemult[strlen(chainemult) + 1] := #0;
903 chainemult[strlen(chainemult)] := temp;
904 end;
905 nombre := nombre mod diviseur;
906 end;
907 diviseur := nombre;
908 { return to 723 }
909
910 for loop := dum_length downto 1 do
911 dummy[loop] := dummy[loop - 1];
912
913 dummy[0] := diviseur;
914 Inc(dum_length);
915 strcpy(PChar(chainemod), PChar(chainemult));
916 until not (strlen(chainemult) <> 0);
917
918 for loop := 0 to dum_length - 1 do
919 begin
920 chainemc[mc_length] := dummy[loop];
921 mc_length := mc_length + 1;
922 end;
923 Inc(j, len);
924 end;
925end;
926
927{ 366 }
928function pdf417(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
929var
930 i, k, j, index_src, index_list, mode, len, loop, offset : Integer;
931 mccorrection : array[0..519] of Integer;
932 total, mc_length, c1, c2, c3, codeerr : Integer;
933 chainemc: TIntegerDynArray = nil;
934 dummy : array[0..34] of Integer;
935 codebarre: TCharDynArray = nil;
936 pattern: TCharDynArray = nil;
937 list: TGlobalList;
938begin
939 SetLength(chainemc, 2700);
940 SetLength(codebarre, 140);
941 SetLength(pattern, 580);
942 codeerr := 0;
943
944 { 456 }
945 index_list := 0;
946 index_src := 0;
947
948 mode := GetMode(Chr(ASource[index_src]));
949
950 for i := 0 to 999 do
951 list[0, i] := 0;
952
953 { 463 }
954 repeat
955 list[1, index_list] := mode;
956 while ((list[1, index_list] = mode) and (index_src < ALength)) do
957 begin
958 Inc(list[0, index_list]);
959 Inc(index_src);
960 mode := GetMode(Chr(ASource[index_src]));
961 end;
962 Inc(index_list);
963 until not (index_src < ALength);
964
965 { 474 }
966 pdfsmooth(index_list, list);
967
968 { 541 - now compress the data }
969 index_src := 0;
970 mc_length := 0;
971 if (ASymbol^.output_options and READER_INIT) <> 0 then
972 begin
973 chainemc[mc_length] := 921; { Reader Initialisation }
974 Inc(mc_length);
975 end;
976 for i := 0 to index_list - 1 do
977 begin
978 case list[1, i] of
979 TEX: { 547 - text mode }
980 textprocess(chainemc, mc_length, PChar(ASource), index_src, list[0, i], i);
981 BYT: { 670 - octet stream mode }
982 byteprocess(chainemc, mc_length, ASource, index_src, list[0, i], i);
983 NUM: { 712 - numeric mode }
984 numbprocess(chainemc, mc_length, PChar(ASource), index_src, list[0, i], i);
985 end;
986 index_src := index_src + list[0, i];
987 end;
988
989 { 752 - Now take care of the number of CWs per row }
990 if (Asymbol^.option_1 < 0) then
991 begin
992 ASymbol^.option_1 := 6;
993 if (mc_length <= 863) then ASymbol^.option_1 := 5;
994 if (mc_length <= 320) then ASymbol^.option_1 := 4;
995 if (mc_length <= 160) then ASymbol^.option_1 := 3;
996 if (mc_length <= 40) then ASymbol^.option_1 := 2;
997 end;
998 k := 1;
999 for loop := 1 to ASymbol^.option_1 + 1 do
1000 k := k * 2;
1001
1002 len := mc_length;
1003 if (ASymbol^.option_2 > 30) then ASymbol^.option_2 := 30;
1004 if (ASymbol^.option_2 < 1) then
1005 ASymbol^.option_2 := Trunc(0.5 + sqrt((len + k) / 3.0));
1006
1007 if (((len + k) / ASymbol^.option_2) > 90) then
1008 { stop the symbol from becoming too high }
1009 ASymbol^.option_2 := ASymbol^.option_2 + 1;
1010
1011 if (len + k > 928) then
1012 begin
1013 { Enforce maximum codeword limit }
1014 result := 2; exit;
1015 end;
1016
1017 if (((len + k) / ASymbol^.option_2) > 90) then
1018 begin
1019 result := 4; exit;
1020 end;
1021
1022 { 781 - Padding calculation }
1023 len := mc_length + 1 + k;
1024 i := 0;
1025 if ((len / ASymbol^.option_2) < 3) then
1026 i := (ASymbol^.option_2 * 3) - len { A bar code must have at least three rows }
1027 else
1028 if ((len mod ASymbol^.option_2) > 0) then
1029 i := ASymbol^.option_2 - len mod ASymbol^.option_2;
1030
1031 { We add the padding }
1032 while (i > 0) do
1033 begin
1034 chainemc[mc_length] := 900;
1035 Inc(mc_length);
1036 Dec(i);
1037 end;
1038 { we add the _length descriptor }
1039 for i := mc_length downto 1 do
1040 chainemc[i] := chainemc[i - 1];
1041 chainemc[0] := mc_length + 1;
1042 Inc(mc_length);
1043
1044 { 796 - we now take care of the Reed Solomon codes }
1045 case ASymbol^.option_1 of
1046 1: offset := 2;
1047 2: offset := 6;
1048 3: offset := 14;
1049 4: offset := 30;
1050 5: offset := 62;
1051 6: offset := 126;
1052 7: offset := 254;
1053 8: offset := 510;
1054 else
1055 offset := 0;
1056 end;
1057
1058 len := mc_length;
1059 for loop := 0 to 519 do
1060 mccorrection[loop] := 0;
1061
1062 //total := 0;
1063 for i := 0 to len - 1 do
1064 begin
1065 total := (chainemc[i] + mccorrection[k - 1]) mod 929;
1066 for j := k - 1 downto 1 do
1067 mccorrection[j] := (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) mod 929) mod 929;
1068 j := 0;
1069 mccorrection[0] := (929 - (total * coefrs[offset + j]) mod 929) mod 929;
1070 end;
1071
1072 { we add these codes to the string }
1073 for i := k - 1 downto 0 do
1074 begin
1075 if mccorrection[i] <> 0 then
1076 chainemc[mc_length] := 929 - mccorrection[i]
1077 else
1078 chainemc[mc_length] := 0;
1079 Inc(mc_length);
1080 end;
1081
1082 { 818 - The CW string is finished }
1083 c1 := (mc_length div ASymbol^.option_2 - 1) div 3;
1084 c2 := ASymbol^.option_1 * 3 + (mc_length div ASymbol^.option_2 - 1) mod 3;
1085 c3 := ASymbol^.option_2 - 1;
1086
1087 { we now encode each row }
1088 for i := 0 to (mc_length div ASymbol^.option_2) - 1 do
1089 begin
1090 for j := 0 to ASymbol^.option_2 - 1 do
1091 dummy[j + 1] := chainemc[i * ASymbol^.option_2 + j];
1092
1093 k := (i div 3) * 30;
1094 case i mod 3 of
1095 { follows this pattern from US Patent 5,243,655:
1096 Row 0: L0 (row #, # of rows) R0 (row #, # of columns)
1097 Row 1: L1 (row #, security level) R1 (row #, # of rows)
1098 Row 2: L2 (row #, # of columns) R2 (row #, security level)
1099 Row 3: L3 (row #, # of rows) R3 (row #, # of columns)
1100 etc. }
1101 0:
1102 begin
1103 dummy[0] := k + c1;
1104 dummy[ASymbol^.option_2 + 1] := k + c3;
1105 end;
1106 1:
1107 begin
1108 dummy[0] := k + c2;
1109 dummy[ASymbol^.option_2 + 1] := k + c1;
1110 end;
1111 2:
1112 begin
1113 dummy[0] := k + c3;
1114 dummy[ASymbol^.option_2 + 1] := k + c2;
1115 end;
1116 end;
1117 strcpy(codebarre, '+*'); { Start with a start char and a separator }
1118 if (ASymbol^.symbology = BARCODE_PDF417TRUNC) then
1119 begin
1120 { truncated - so same as before except knock off the last 5 chars }
1121 for j := 0 to ASymbol^.option_2 do
1122 begin
1123 case i mod 3 of
1124 1: offset := 929;
1125 2: offset := 1858;
1126 else
1127 offset := 0;
1128 end;
1129 concat(codebarre[0], PChar(codagemc[offset + dummy[j]]));
1130 concat(codebarre[0], '*');
1131 end;
1132 end
1133 else
1134 begin
1135 { normal PDF417 symbol }
1136 for j := 0 to ASymbol^.option_2 + 1 do
1137 begin
1138 case i mod 3 of
1139 1: offset := 929; { cluster(3) }
1140 2: offset := 1858; { cluster(6) }
1141 else
1142 offset := 0; { cluster(0) }
1143 end;
1144 concat(codebarre, PChar(codagemc[offset + dummy[j]]));
1145 concat(codebarre, '*');
1146 end;
1147 concat(codebarre, '-');
1148 end;
1149
1150 strcpy(pattern, '');
1151 for loop := 0 to strlen(codebarre) - 1 do
1152 lookup(PChar(BRSET), PDFttf, codebarre[loop], pattern);
1153
1154 for loop := 0 to strlen(pattern) - 1 do
1155 if (pattern[loop] = '1') then set_module(ASymbol, i, loop);
1156
1157 //if (symbol.height = 0) then
1158 ASymbol^.row_height[i] := 3;
1159 end;
1160 ASymbol^.rows := (mc_length div ASymbol^.option_2);
1161 ASymbol^.width := strlen(pattern);
1162
1163 { 843 }
1164 result := codeerr; exit;
1165end;
1166
1167{ 345 }
1168function pdf417enc(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
1169var
1170 codeerr: Integer;
1171begin
1172 Result := 0;
1173
1174 if ((ASymbol^.option_1 < -1) or (ASymbol^.option_1 > 8)) then
1175 begin
1176 ASymbol^.SetErrorText('Security value out of range');
1177 Asymbol^.option_1 := -1;
1178 Result := WARN_INVALID_OPTION;
1179 end;
1180
1181 if ((ASymbol^.option_2 < 0) or (ASymbol^.option_2 > 30)) then
1182 begin
1183 ASymbol^.SetErrorText('Number of columns out of range (max 30)');
1184 ASymbol^.option_2 := 0;
1185 Result := WARN_INVALID_OPTION;
1186 end;
1187
1188 { 349 }
1189 codeerr := pdf417(ASymbol, ASource, ALength);
1190
1191 { 352 }
1192 if (codeerr <> 0) then
1193 begin
1194 case codeerr of
1195 1:
1196 begin
1197 ASymbol^.SetErrorText('No such file or file unreadable');
1198 Result := ERROR_INVALID_OPTION;
1199 end;
1200 2:
1201 begin
1202 ASymbol^.SetErrorText('Input string too long');
1203 Result := ERROR_TOO_LONG;
1204 end;
1205 3:
1206 begin
1207 ASymbol^.SetErrorText('Number of codewords per row too small');
1208 Result := WARN_INVALID_OPTION;
1209 end;
1210 4:
1211 begin
1212 ASymbol^.SetErrorText('Data too long for specified number of columns');
1213 Result := ERROR_TOO_LONG;
1214 end;
1215 else
1216 ASymbol^.SetErrorText('Something strange happened');
1217 Result := ERROR_ENCODING_PROBLEM;
1218 end;
1219 end;
1220end;
1221
1222{ Like PDF417 only much smaller! }
1223function micro_pdf417(ASymbol: PZintSymbol; ASource: PByte; ALength: Integer): Integer;
1224var
1225 i, k, j, index_src, index_list, mode, len, offset : Integer;
1226 mccorrection : array[0..49] of Integer;
1227 total, mc_length, codeerr : Integer;
1228 chainemc: TIntegerDynArray = nil;
1229 dummy : array[0..5] of Integer;
1230 codebarre: TCharDynArray = nil;
1231 pattern: TCharDynArray = nil;
1232 variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster : Integer;
1233 LeftRAP, CentreRAP, RightRAP, Cluster, writer, flip, loop : Integer;
1234 list: TGlobalList;
1235begin
1236 SetLength(chainemc, 2700);
1237 SetLength(codebarre, 100);
1238 SetLength(pattern, 580);
1239
1240 { Encoding starts out the same as PDF417, so use the same code }
1241 codeerr := 0;
1242
1243 { 456 }
1244 index_list := 0;
1245 index_src := 0;
1246
1247 mode := GetMode(Chr(ASource[index_src]));
1248
1249 for i := 0 to 999 do
1250 list[0, i] := 0;
1251
1252 { 463 }
1253 repeat
1254 list[1, index_list] := mode;
1255 while ((list[1, index_list] = mode) and (index_src < ALength)) do
1256 begin
1257 Inc(list[0, index_list]);
1258 Inc(index_src);
1259 mode := GetMode(Chr(ASource[index_src]));
1260 end;
1261 Inc(index_list);
1262 until not (index_src < ALength);
1263
1264 { 474 }
1265 pdfsmooth(index_list, list);
1266
1267 { 541 - now compress the data }
1268 index_src := 0;
1269 mc_length := 0;
1270 if (ASymbol^.output_options and READER_INIT) <> 0 then
1271 begin
1272 chainemc[mc_length] := 921; { Reader Initialisation }
1273 Inc(mc_length);
1274 end;
1275 for i := 0 to index_list - 1 do
1276 begin
1277 case list[1, i] of
1278 TEX: { 547 - text mode }
1279 textprocess(chainemc, mc_length, PChar(ASource), index_src, list[0, i], i);
1280 BYT: { 670 - octet stream mode }
1281 byteprocess(chainemc, mc_length, ASource, index_src, list[0, i], i);
1282 NUM: { 712 - numeric mode }
1283 numbprocess(chainemc, mc_length, PChar(ASource), index_src, list[0, i], i);
1284 end;
1285 index_src := index_src + list[0, i];
1286 end;
1287
1288 { This is where it all changes! }
1289
1290 if (mc_length > 126) then
1291 begin
1292 ASymbol^.SetErrorText('Input data too long.');
1293 result := ERROR_TOO_LONG;
1294 exit;
1295 end;
1296
1297 if (ASymbol^.option_2 > 4) then
1298 begin
1299 ASymbol^.SetErrorText('Specified width out of range');
1300 ASymbol^.option_2 := 0;
1301 codeerr := WARN_INVALID_OPTION;
1302 end;
1303
1304 { Now figure out which variant of the symbol to use and load values accordingly }
1305
1306 variant := 0;
1307
1308 if ((ASymbol^.option_2 = 1) and (mc_length > 20)) then
1309 begin
1310 { the user specified 1 column but the data doesn't fit - go to automatic }
1311 ASymbol^.option_2 := 0;
1312 ASymbol^.SetErrorText('Specified symbol size too small for data');
1313 codeerr := WARN_INVALID_OPTION;
1314 end;
1315
1316 if ((ASymbol^.option_2 = 2) and (mc_length > 37)) then
1317 begin
1318 { the user specified 2 columns but the data doesn't fit - go to automatic }
1319 ASymbol^.option_2 := 0;
1320 ASymbol^.SetErrorText('Specified symbol size too small for data');
1321 codeerr := WARN_INVALID_OPTION;
1322 end;
1323
1324 if ((ASymbol^.option_2 = 3) and (mc_length > 82)) then
1325 begin
1326 { the user specified 3 columns but the data doesn't fit - go to automatic }
1327 ASymbol^.option_2 := 0;
1328 ASymbol^.SetErrorText('Specified symbol size too small for data');
1329 codeerr := WARN_INVALID_OPTION;
1330 end;
1331
1332 if (ASymbol^.option_2 = 1) then
1333 begin
1334 { the user specified 1 column and the data does fit }
1335 variant := 6;
1336 if (mc_length <= 16) then variant := 5;
1337 if (mc_length <= 12) then variant := 4;
1338 if (mc_length <= 10) then variant := 3;
1339 if (mc_length <= 7) then variant := 2;
1340 if (mc_length <= 4) then variant := 1;
1341 end;
1342
1343 if (ASymbol^.option_2 = 2) then
1344 begin
1345 { the user specified 2 columns and the data does fit }
1346 variant := 13;
1347 if (mc_length <= 33) then variant := 12;
1348 if (mc_length <= 29) then variant := 11;
1349 if (mc_length <= 24) then variant := 10;
1350 if (mc_length <= 19) then variant := 9;
1351 if (mc_length <= 13) then variant := 8;
1352 if (mc_length <= 8) then variant := 7;
1353 end;
1354
1355 if (ASymbol^.option_2 = 3) then
1356 begin
1357 { the user specified 3 columns and the data does fit }
1358 variant := 23;
1359 if (mc_length <= 70) then variant := 22;
1360 if (mc_length <= 58) then variant := 21;
1361 if (mc_length <= 46) then variant := 20;
1362 if (mc_length <= 34) then variant := 19;
1363 if (mc_length <= 24) then variant := 18;
1364 if (mc_length <= 18) then variant := 17;
1365 if (mc_length <= 14) then variant := 16;
1366 if (mc_length <= 10) then variant := 15;
1367 if (mc_length <= 6) then variant := 14;
1368 end;
1369
1370 if (ASymbol^.option_2 = 4) then
1371 begin
1372 { the user specified 4 columns and the data does fit }
1373 variant := 34;
1374 if (mc_length <= 108) then variant := 33;
1375 if (mc_length <= 90) then variant := 32;
1376 if (mc_length <= 72) then variant := 31;
1377 if (mc_length <= 54) then variant := 30;
1378 if (mc_length <= 39) then variant := 29;
1379 if (mc_length <= 30) then variant := 28;
1380 if (mc_length <= 24) then variant := 27;
1381 if (mc_length <= 18) then variant := 26;
1382 if (mc_length <= 12) then variant := 25;
1383 if (mc_length <= 8) then variant := 24;
1384 end;
1385
1386 if (variant = 0) then
1387 begin
1388 { Zint can choose automatically from all available variations }
1389 for i := 27 downto 0 do
1390 begin
1391 if (MicroAutosize[i] >= mc_length) then
1392 variant := MicroAutosize[i + 28];
1393 end;
1394 end;
1395
1396 { Now we have the variant we can load the data }
1397 Dec(variant);
1398 ASymbol^.option_2 := MicroVariants[variant]; { columns }
1399 ASymbol^.rows := MicroVariants[variant + 34]; { rows }
1400 k := MicroVariants[variant + 68]; { number of EC CWs }
1401 len := (ASymbol^.option_2 * ASymbol^.rows) - k; { number of non-EC CWs }
1402 i := len - mc_length; { amount of padding required }
1403 offset := MicroVariants[variant + 102]; { coefficient offset }
1404
1405 { We add the padding }
1406 while (i > 0) do
1407 begin
1408 chainemc[mc_length] := 900;
1409 Inc(mc_length);
1410 Dec(i);
1411 end;
1412
1413 { Reed-Solomon error correction }
1414 len := mc_length;
1415 for loop := 0 to 49 do
1416 mccorrection[loop] := 0;
1417
1418 for i := 0 to len - 1 do
1419 begin
1420 total := (chainemc[i] + mccorrection[k - 1]) mod 929;
1421 for j := k - 1 downto 0 do
1422 begin
1423 if (j = 0) then
1424 mccorrection[j] := (929 - (total * Microcoeffs[offset + j]) mod 929) mod 929
1425 else
1426 mccorrection[j] := (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) mod 929) mod 929;
1427 end;
1428 end;
1429
1430 for j := 0 to k - 1 do
1431 if (mccorrection[j] <> 0) then mccorrection[j] := 929 - mccorrection[j];
1432
1433 { we add these codes to the string }
1434 for i := k - 1 downto 0 do
1435 begin
1436 chainemc[mc_length] := mccorrection[i];
1437 Inc(mc_length);
1438 end;
1439
1440 { Now get the RAP (Row Address Pattern) start values }
1441 LeftRAPStart := RAPTable[variant];
1442 CentreRAPStart := RAPTable[variant + 34];
1443 RightRAPStart := RAPTable[variant + 68];
1444 StartCluster := RAPTable[variant + 102] div 3;
1445
1446 { That's all values loaded, get on with the encoding }
1447
1448 LeftRAP := LeftRAPStart;
1449 CentreRAP := CentreRAPStart;
1450 RightRAP := RightRAPStart;
1451 Cluster := StartCluster; { Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) }
1452
1453 for i := 0 to ASymbol^.rows - 1 do
1454 begin
1455 strcpy(codebarre, '');
1456 offset := 929 * Cluster;
1457 for j := 0 to 4 do
1458 dummy[j] := 0;
1459
1460 for j := 0 to ASymbol^.option_2 - 1 do
1461 dummy[j + 1] := chainemc[i * ASymbol^.option_2 + j];
1462
1463 { Copy the data into codebarre }
1464 concat(codebarre, PChar(RAPLR[LeftRAP]));
1465 concat(codebarre, '1');
1466 concat(codebarre, PChar(codagemc[offset + dummy[1]]));
1467 concat(codebarre, '1');
1468 if (ASymbol^.option_2 = 3) then
1469 concat(codebarre, PChar(RAPC[CentreRAP]));
1470
1471 if (ASymbol^.option_2 >= 2) then
1472 begin
1473 concat(codebarre, '1');
1474 concat(codebarre, PChar(codagemc[offset + dummy[2]]));
1475 concat(codebarre, '1');
1476 end;
1477 if (ASymbol^.option_2 = 4) then
1478 concat(codebarre, PChar(RAPC[CentreRAP]));
1479
1480 if (ASymbol^.option_2 >= 3) then
1481 begin
1482 concat(codebarre, '1');
1483 concat(codebarre, PChar(codagemc[offset + dummy[3]]));
1484 concat(codebarre, '1');
1485 end;
1486 if (ASymbol^.option_2 = 4) then
1487 begin
1488 concat(codebarre, '1');
1489 concat(codebarre, PChar(codagemc[offset + dummy[4]]));
1490 concat(codebarre, '1');
1491 end;
1492 concat(codebarre, PChar(RAPLR[RightRAP]));
1493 concat(codebarre, '1'); { stop }
1494
1495 { Now codebarre is a mixture of letters and numbers }
1496
1497 writer := 0;
1498 flip := 1;
1499 strcpy(pattern, '');
1500 for loop := 0 to strlen(codebarre) - 1 do
1501 begin
1502 if ((codebarre[loop] >= '0') and (codebarre[loop] <= '9')) then
1503 begin
1504 for k := 0 to ctoi(codebarre[loop]) - 1 do
1505 begin
1506 if (flip = 0) then
1507 pattern[writer] := '0'
1508 else
1509 pattern[writer] := '1';
1510 Inc(writer);
1511 end;
1512 pattern[writer] := #0;
1513 if (flip = 0) then
1514 flip := 1
1515 else
1516 flip := 0;
1517 end
1518 else
1519 begin
1520 lookup(PChar(BRSET), PDFttf, codebarre[loop], pattern);
1521 Inc(writer, 5);
1522 end;
1523 end;
1524 ASymbol^.width := writer;
1525
1526 { so now pattern[] holds the string of '1's and '0's. - copy this to the symbol }
1527 for loop := 0 to strlen(pattern) - 1 do
1528 if (pattern[loop] = '1') then set_module(ASymbol, i, loop);
1529
1530 Asymbol^.row_height[i] := 2;
1531
1532 { Set up RAPs and Cluster for next row }
1533 Inc(LeftRAP);
1534 Inc(CentreRAP);
1535 Inc(RightRAP);
1536 Inc(Cluster);
1537
1538 if (LeftRAP = 53) then
1539 LeftRAP := 1;
1540
1541 if (CentreRAP = 53) then
1542 CentreRAP := 1;
1543
1544 if (RightRAP = 53) then
1545 RightRAP := 1;
1546
1547 if (Cluster = 3) then
1548 Cluster := 0;
1549 end;
1550
1551 Result := codeerr;
1552end;
1553
1554end.
1555
Note: See TracBrowser for help on using the repository browser.