181 |
ilm |
1 |
/*
|
|
|
2 |
* Copyright 2014 Robin Stuart
|
|
|
3 |
*
|
|
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
|
5 |
* in compliance with the License. You may obtain a copy of the License at
|
|
|
6 |
*
|
|
|
7 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
8 |
*
|
|
|
9 |
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
|
10 |
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
|
11 |
* or implied. See the License for the specific language governing permissions and limitations under
|
|
|
12 |
* the License.
|
|
|
13 |
*/
|
|
|
14 |
package uk.org.okapibarcode.backend;
|
|
|
15 |
|
|
|
16 |
import static uk.org.okapibarcode.util.Arrays.positionOf;
|
|
|
17 |
|
|
|
18 |
import java.awt.geom.Rectangle2D;
|
|
|
19 |
import java.math.BigInteger;
|
|
|
20 |
import java.util.ArrayList;
|
|
|
21 |
import java.util.List;
|
|
|
22 |
|
|
|
23 |
import uk.org.okapibarcode.backend.DataBar14.Mode;
|
|
|
24 |
|
|
|
25 |
/**
|
|
|
26 |
* <p>
|
|
|
27 |
* Implements GS1 Composite symbology according to ISO/IEC 24723:2010.
|
|
|
28 |
*
|
|
|
29 |
* <p>
|
|
|
30 |
* Composite symbols comprise a 2D element which encodes GS1 data and a "linear" element which can
|
|
|
31 |
* be UPC, EAN, Code 128 or GS1 DataBar symbol.
|
|
|
32 |
*
|
|
|
33 |
* @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
|
|
|
34 |
*/
|
|
|
35 |
public class Composite extends Symbol {
|
|
|
36 |
|
|
|
37 |
/** The linear component choices available. */
|
|
|
38 |
public static enum LinearEncoding {
|
|
|
39 |
UPCA, UPCE, EAN, CODE_128, DATABAR_14, DATABAR_14_STACK, DATABAR_14_STACK_OMNI, DATABAR_LIMITED, DATABAR_EXPANDED, DATABAR_EXPANDED_STACK
|
|
|
40 |
}
|
|
|
41 |
|
|
|
42 |
/** The 2D component choices available. */
|
|
|
43 |
public static enum CompositeMode {
|
|
|
44 |
/**
|
|
|
45 |
* Indicates that the composite symbol uses a MicroPDF417 variant as the 2D component. Of
|
|
|
46 |
* the 2D component choices, this one holds the least amount of data.
|
|
|
47 |
*/
|
|
|
48 |
CC_A,
|
|
|
49 |
/**
|
|
|
50 |
* Indicates that the composite symbol uses a MicroPDF417 symbol as the 2D component,
|
|
|
51 |
* starting with a codeword of 920.
|
|
|
52 |
*/
|
|
|
53 |
CC_B,
|
|
|
54 |
/**
|
|
|
55 |
* Indicates that the composite symbol uses a PDF417 symbol as the 2D component, starting
|
|
|
56 |
* with a codeword of 920. Of the 2D component choices, this one holds the most amount of
|
|
|
57 |
* data. May only be used if the linear component is {@link LinearEncoding#CODE_128 Code
|
|
|
58 |
* 128}.
|
|
|
59 |
*/
|
|
|
60 |
CC_C
|
|
|
61 |
}
|
|
|
62 |
|
|
|
63 |
private static enum GeneralFieldMode {
|
|
|
64 |
NUMERIC, ALPHA, ISOIEC, INVALID_CHAR, ANY_ENC, ALPHA_OR_ISO
|
|
|
65 |
}
|
|
|
66 |
|
|
|
67 |
/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */
|
|
|
68 |
private static final int[] CCA_COEFFS = {
|
|
|
69 |
/* k = 4 */
|
|
|
70 |
522, 568, 723, 809,
|
|
|
71 |
/* k = 5 */
|
|
|
72 |
427, 919, 460, 155, 566,
|
|
|
73 |
/* k = 6 */
|
|
|
74 |
861, 285, 19, 803, 17, 766,
|
|
|
75 |
/* k = 7 */
|
|
|
76 |
76, 925, 537, 597, 784, 691, 437,
|
|
|
77 |
/* k = 8 */
|
|
|
78 |
237, 308, 436, 284, 646, 653, 428, 379 };
|
|
|
79 |
|
|
|
80 |
private static final int[] COEFRS = {
|
|
|
81 |
/* k = 2 */
|
|
|
82 |
27, 917,
|
|
|
83 |
/* k = 4 */
|
|
|
84 |
522, 568, 723, 809,
|
|
|
85 |
/* k = 8 */
|
|
|
86 |
237, 308, 436, 284, 646, 653, 428, 379,
|
|
|
87 |
/* k = 16 */
|
|
|
88 |
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
|
|
|
89 |
/* k = 32 */
|
|
|
90 |
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
|
|
|
91 |
/* k = 64 */
|
|
|
92 |
539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460, 594,
|
|
|
93 |
225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543,
|
|
|
94 |
/* k = 128 */
|
|
|
95 |
521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594, 723,
|
|
|
96 |
674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48,
|
|
|
97 |
228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, 211, 330,
|
|
|
98 |
539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539,
|
|
|
99 |
/* k = 256 */
|
|
|
100 |
524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68, 569, 11,
|
|
|
101 |
204, 796, 605, 540, 913, 801, 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334,
|
|
|
102 |
376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, 2, 290, 743, 199,
|
|
|
103 |
655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, 689, 707,
|
|
|
104 |
805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73,
|
|
|
105 |
914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167, 29, 872, 449,
|
|
|
106 |
83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10,
|
|
|
107 |
/* k = 512 */
|
|
|
108 |
352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435, 543,
|
|
|
109 |
203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107,
|
|
|
110 |
784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, 240, 518,
|
|
|
111 |
794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, 861,
|
|
|
112 |
841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533,
|
|
|
113 |
820, 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245,
|
|
|
114 |
288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109,
|
|
|
115 |
608, 563, 365, 181, 772, 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, 787,
|
|
|
116 |
680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242, 797, 838, 837, 720, 224, 307,
|
|
|
117 |
631, 61, 87, 560, 310, 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281,
|
|
|
118 |
73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720,
|
|
|
119 |
742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762,
|
|
|
120 |
752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849,
|
|
|
121 |
647, 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 };
|
|
|
122 |
|
|
|
123 |
/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */
|
|
|
124 |
private static final int[] CCA_VARIANTS = { 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9,
|
|
|
125 |
15, 22 };
|
|
|
126 |
|
|
|
127 |
/*
|
|
|
128 |
* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables
|
|
|
129 |
* 10 and 11
|
|
|
130 |
*/
|
|
|
131 |
private static final int[] A_RAP_TABLE = { 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9, 19, 33, 12, 40, 46, 23, 52,
|
|
|
132 |
23, 13, 17, 27, 33, 52, 3, 6, 46, 41, 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 };
|
|
|
133 |
|
|
|
134 |
private static final String[] CODAGEMC = { "urA", "xfs", "ypy", "unk", "xdw", "yoz", "pDA", "uls", "pBk", "eBA", "pAs", "eAk", "prA", "uvs", "xhy", "pnk", "utw", "xgz", "fDA", "pls", "fBk", "frA",
|
|
|
135 |
"pvs", "uxy", "fnk", "ptw", "uwz", "fls", "psy", "fvs", "pxy", "ftw", "pwz", "fxy", "yrx", "ufk", "xFw", "ymz", "onA", "uds", "xEy", "olk", "ucw", "dBA", "oks", "uci", "dAk", "okg", "dAc",
|
|
|
136 |
"ovk", "uhw", "xaz", "dnA", "ots", "ugy", "dlk", "osw", "ugj", "dks", "osi", "dvk", "oxw", "uiz", "dts", "owy", "dsw", "owj", "dxw", "oyz", "dwy", "dwj", "ofA", "uFs", "xCy", "odk", "uEw",
|
|
|
137 |
"xCj", "clA", "ocs", "uEi", "ckk", "ocg", "ckc", "ckE", "cvA", "ohs", "uay", "ctk", "ogw", "uaj", "css", "ogi", "csg", "csa", "cxs", "oiy", "cww", "oij", "cwi", "cyy", "oFk", "uCw", "xBj",
|
|
|
138 |
"cdA", "oEs", "uCi", "cck", "oEg", "uCb", "ccc", "oEa", "ccE", "oED", "chk", "oaw", "uDj", "cgs", "oai", "cgg", "oab", "cga", "cgD", "obj", "cib", "cFA", "oCs", "uBi", "cEk", "oCg", "uBb",
|
|
|
139 |
"cEc", "oCa", "cEE", "oCD", "cEC", "cas", "cag", "caa", "cCk", "uAr", "oBa", "oBD", "cCB", "tfk", "wpw", "yez", "mnA", "tds", "woy", "mlk", "tcw", "woj", "FBA", "mks", "FAk", "mvk", "thw",
|
|
|
140 |
"wqz", "FnA", "mts", "tgy", "Flk", "msw", "Fks", "Fkg", "Fvk", "mxw", "tiz", "Fts", "mwy", "Fsw", "Fsi", "Fxw", "myz", "Fwy", "Fyz", "vfA", "xps", "yuy", "vdk", "xow", "yuj", "qlA", "vcs",
|
|
|
141 |
"xoi", "qkk", "vcg", "xob", "qkc", "vca", "mfA", "tFs", "wmy", "qvA", "mdk", "tEw", "wmj", "qtk", "vgw", "xqj", "hlA", "Ekk", "mcg", "tEb", "hkk", "qsg", "hkc", "EvA", "mhs", "tay", "hvA",
|
|
|
142 |
"Etk", "mgw", "taj", "htk", "qww", "vij", "hss", "Esg", "hsg", "Exs", "miy", "hxs", "Eww", "mij", "hww", "qyj", "hwi", "Eyy", "hyy", "Eyj", "hyj", "vFk", "xmw", "ytj", "qdA", "vEs", "xmi",
|
|
|
143 |
"qck", "vEg", "xmb", "qcc", "vEa", "qcE", "qcC", "mFk", "tCw", "wlj", "qhk", "mEs", "tCi", "gtA", "Eck", "vai", "tCb", "gsk", "Ecc", "mEa", "gsc", "qga", "mED", "EcC", "Ehk", "maw", "tDj",
|
|
|
144 |
"gxk", "Egs", "mai", "gws", "qii", "mab", "gwg", "Ega", "EgD", "Eiw", "mbj", "gyw", "Eii", "gyi", "Eib", "gyb", "gzj", "qFA", "vCs", "xli", "qEk", "vCg", "xlb", "qEc", "vCa", "qEE", "vCD",
|
|
|
145 |
"qEC", "qEB", "EFA", "mCs", "tBi", "ghA", "EEk", "mCg", "tBb", "ggk", "qag", "vDb", "ggc", "EEE", "mCD", "ggE", "qaD", "ggC", "Eas", "mDi", "gis", "Eag", "mDb", "gig", "qbb", "gia", "EaD",
|
|
|
146 |
"giD", "gji", "gjb", "qCk", "vBg", "xkr", "qCc", "vBa", "qCE", "vBD", "qCC", "qCB", "ECk", "mBg", "tAr", "gak", "ECc", "mBa", "gac", "qDa", "mBD", "gaE", "ECC", "gaC", "ECB", "EDg", "gbg",
|
|
|
147 |
"gba", "gbD", "vAq", "vAn", "qBB", "mAq", "EBE", "gDE", "gDC", "gDB", "lfA", "sps", "wey", "ldk", "sow", "ClA", "lcs", "soi", "Ckk", "lcg", "Ckc", "CkE", "CvA", "lhs", "sqy", "Ctk", "lgw",
|
|
|
148 |
"sqj", "Css", "lgi", "Csg", "Csa", "Cxs", "liy", "Cww", "lij", "Cwi", "Cyy", "Cyj", "tpk", "wuw", "yhj", "ndA", "tos", "wui", "nck", "tog", "wub", "ncc", "toa", "ncE", "toD", "lFk", "smw",
|
|
|
149 |
"wdj", "nhk", "lEs", "smi", "atA", "Cck", "tqi", "smb", "ask", "ngg", "lEa", "asc", "CcE", "asE", "Chk", "law", "snj", "axk", "Cgs", "trj", "aws", "nii", "lab", "awg", "Cga", "awa", "Ciw",
|
|
|
150 |
"lbj", "ayw", "Cii", "ayi", "Cib", "Cjj", "azj", "vpA", "xus", "yxi", "vok", "xug", "yxb", "voc", "xua", "voE", "xuD", "voC", "nFA", "tms", "wti", "rhA", "nEk", "xvi", "wtb", "rgk", "vqg",
|
|
|
151 |
"xvb", "rgc", "nEE", "tmD", "rgE", "vqD", "nEB", "CFA", "lCs", "sli", "ahA", "CEk", "lCg", "slb", "ixA", "agk", "nag", "tnb", "iwk", "rig", "vrb", "lCD", "iwc", "agE", "naD", "iwE", "CEB",
|
|
|
152 |
"Cas", "lDi", "ais", "Cag", "lDb", "iys", "aig", "nbb", "iyg", "rjb", "CaD", "aiD", "Cbi", "aji", "Cbb", "izi", "ajb", "vmk", "xtg", "ywr", "vmc", "xta", "vmE", "xtD", "vmC", "vmB", "nCk",
|
|
|
153 |
"tlg", "wsr", "rak", "nCc", "xtr", "rac", "vna", "tlD", "raE", "nCC", "raC", "nCB", "raB", "CCk", "lBg", "skr", "aak", "CCc", "lBa", "iik", "aac", "nDa", "lBD", "iic", "rba", "CCC", "iiE",
|
|
|
154 |
"aaC", "CCB", "aaB", "CDg", "lBr", "abg", "CDa", "ijg", "aba", "CDD", "ija", "abD", "CDr", "ijr", "vlc", "xsq", "vlE", "xsn", "vlC", "vlB", "nBc", "tkq", "rDc", "nBE", "tkn", "rDE", "vln",
|
|
|
155 |
"rDC", "nBB", "rDB", "CBc", "lAq", "aDc", "CBE", "lAn", "ibc", "aDE", "nBn", "ibE", "rDn", "CBB", "ibC", "aDB", "ibB", "aDq", "ibq", "ibn", "xsf", "vkl", "tkf", "nAm", "nAl", "CAo", "aBo",
|
|
|
156 |
"iDo", "CAl", "aBl", "kpk", "BdA", "kos", "Bck", "kog", "seb", "Bcc", "koa", "BcE", "koD", "Bhk", "kqw", "sfj", "Bgs", "kqi", "Bgg", "kqb", "Bga", "BgD", "Biw", "krj", "Bii", "Bib", "Bjj",
|
|
|
157 |
"lpA", "sus", "whi", "lok", "sug", "loc", "sua", "loE", "suD", "loC", "BFA", "kms", "sdi", "DhA", "BEk", "svi", "sdb", "Dgk", "lqg", "svb", "Dgc", "BEE", "kmD", "DgE", "lqD", "BEB", "Bas",
|
|
|
158 |
"kni", "Dis", "Bag", "knb", "Dig", "lrb", "Dia", "BaD", "Bbi", "Dji", "Bbb", "Djb", "tuk", "wxg", "yir", "tuc", "wxa", "tuE", "wxD", "tuC", "tuB", "lmk", "stg", "nqk", "lmc", "sta", "nqc",
|
|
|
159 |
"tva", "stD", "nqE", "lmC", "nqC", "lmB", "nqB", "BCk", "klg", "Dak", "BCc", "str", "bik", "Dac", "lna", "klD", "bic", "nra", "BCC", "biE", "DaC", "BCB", "DaB", "BDg", "klr", "Dbg", "BDa",
|
|
|
160 |
"bjg", "Dba", "BDD", "bja", "DbD", "BDr", "Dbr", "bjr", "xxc", "yyq", "xxE", "yyn", "xxC", "xxB", "ttc", "wwq", "vvc", "xxq", "wwn", "vvE", "xxn", "vvC", "ttB", "vvB", "llc", "ssq", "nnc",
|
|
|
161 |
"llE", "ssn", "rrc", "nnE", "ttn", "rrE", "vvn", "llB", "rrC", "nnB", "rrB", "BBc", "kkq", "DDc", "BBE", "kkn", "bbc", "DDE", "lln", "jjc", "bbE", "nnn", "BBB", "jjE", "rrn", "DDB", "jjC",
|
|
|
162 |
"BBq", "DDq", "BBn", "bbq", "DDn", "jjq", "bbn", "jjn", "xwo", "yyf", "xwm", "xwl", "tso", "wwf", "vto", "xwv", "vtm", "tsl", "vtl", "lko", "ssf", "nlo", "lkm", "rno", "nlm", "lkl", "rnm",
|
|
|
163 |
"nll", "rnl", "BAo", "kkf", "DBo", "lkv", "bDo", "DBm", "BAl", "jbo", "bDm", "DBl", "jbm", "bDl", "jbl", "DBv", "jbv", "xwd", "vsu", "vst", "nku", "rlu", "rlt", "DAu", "bBu", "jDu", "jDt",
|
|
|
164 |
"ApA", "Aok", "keg", "Aoc", "AoE", "AoC", "Aqs", "Aqg", "Aqa", "AqD", "Ari", "Arb", "kuk", "kuc", "sha", "kuE", "shD", "kuC", "kuB", "Amk", "kdg", "Bqk", "kvg", "kda", "Bqc", "kva", "BqE",
|
|
|
165 |
"kvD", "BqC", "AmB", "BqB", "Ang", "kdr", "Brg", "kvr", "Bra", "AnD", "BrD", "Anr", "Brr", "sxc", "sxE", "sxC", "sxB", "ktc", "lvc", "sxq", "sgn", "lvE", "sxn", "lvC", "ktB", "lvB", "Alc",
|
|
|
166 |
"Bnc", "AlE", "kcn", "Drc", "BnE", "AlC", "DrE", "BnC", "AlB", "DrC", "BnB", "Alq", "Bnq", "Aln", "Drq", "Bnn", "Drn", "wyo", "wym", "wyl", "swo", "txo", "wyv", "txm", "swl", "txl", "kso",
|
|
|
167 |
"sgf", "lto", "swv", "nvo", "ltm", "ksl", "nvm", "ltl", "nvl", "Ako", "kcf", "Blo", "ksv", "Dno", "Blm", "Akl", "bro", "Dnm", "Bll", "brm", "Dnl", "Akv", "Blv", "Dnv", "brv", "yze", "yzd",
|
|
|
168 |
"wye", "xyu", "wyd", "xyt", "swe", "twu", "swd", "vxu", "twt", "vxt", "kse", "lsu", "ksd", "ntu", "lst", "rvu", "ypk", "zew", "xdA", "yos", "zei", "xck", "yog", "zeb", "xcc", "yoa", "xcE",
|
|
|
169 |
"yoD", "xcC", "xhk", "yqw", "zfj", "utA", "xgs", "yqi", "usk", "xgg", "yqb", "usc", "xga", "usE", "xgD", "usC", "uxk", "xiw", "yrj", "ptA", "uws", "xii", "psk", "uwg", "xib", "psc", "uwa",
|
|
|
170 |
"psE", "uwD", "psC", "pxk", "uyw", "xjj", "ftA", "pws", "uyi", "fsk", "pwg", "uyb", "fsc", "pwa", "fsE", "pwD", "fxk", "pyw", "uzj", "fws", "pyi", "fwg", "pyb", "fwa", "fyw", "pzj", "fyi",
|
|
|
171 |
"fyb", "xFA", "yms", "zdi", "xEk", "ymg", "zdb", "xEc", "yma", "xEE", "ymD", "xEC", "xEB", "uhA", "xas", "yni", "ugk", "xag", "ynb", "ugc", "xaa", "ugE", "xaD", "ugC", "ugB", "oxA", "uis",
|
|
|
172 |
"xbi", "owk", "uig", "xbb", "owc", "uia", "owE", "uiD", "owC", "owB", "dxA", "oys", "uji", "dwk", "oyg", "ujb", "dwc", "oya", "dwE", "oyD", "dwC", "dys", "ozi", "dyg", "ozb", "dya", "dyD",
|
|
|
173 |
"dzi", "dzb", "xCk", "ylg", "zcr", "xCc", "yla", "xCE", "ylD", "xCC", "xCB", "uak", "xDg", "ylr", "uac", "xDa", "uaE", "xDD", "uaC", "uaB", "oik", "ubg", "xDr", "oic", "uba", "oiE", "ubD",
|
|
|
174 |
"oiC", "oiB", "cyk", "ojg", "ubr", "cyc", "oja", "cyE", "ojD", "cyC", "cyB", "czg", "ojr", "cza", "czD", "czr", "xBc", "ykq", "xBE", "ykn", "xBC", "xBB", "uDc", "xBq", "uDE", "xBn", "uDC",
|
|
|
175 |
"uDB", "obc", "uDq", "obE", "uDn", "obC", "obB", "cjc", "obq", "cjE", "obn", "cjC", "cjB", "cjq", "cjn", "xAo", "ykf", "xAm", "xAl", "uBo", "xAv", "uBm", "uBl", "oDo", "uBv", "oDm", "oDl",
|
|
|
176 |
"cbo", "oDv", "cbm", "cbl", "xAe", "xAd", "uAu", "uAt", "oBu", "oBt", "wpA", "yes", "zFi", "wok", "yeg", "zFb", "woc", "yea", "woE", "yeD", "woC", "woB", "thA", "wqs", "yfi", "tgk", "wqg",
|
|
|
177 |
"yfb", "tgc", "wqa", "tgE", "wqD", "tgC", "tgB", "mxA", "tis", "wri", "mwk", "tig", "wrb", "mwc", "tia", "mwE", "tiD", "mwC", "mwB", "FxA", "mys", "tji", "Fwk", "myg", "tjb", "Fwc", "mya",
|
|
|
178 |
"FwE", "myD", "FwC", "Fys", "mzi", "Fyg", "mzb", "Fya", "FyD", "Fzi", "Fzb", "yuk", "zhg", "hjs", "yuc", "zha", "hbw", "yuE", "zhD", "hDy", "yuC", "yuB", "wmk", "ydg", "zEr", "xqk", "wmc",
|
|
|
179 |
"zhr", "xqc", "yva", "ydD", "xqE", "wmC", "xqC", "wmB", "xqB", "tak", "wng", "ydr", "vik", "tac", "wna", "vic", "xra", "wnD", "viE", "taC", "viC", "taB", "viB", "mik", "tbg", "wnr", "qyk",
|
|
|
180 |
"mic", "tba", "qyc", "vja", "tbD", "qyE", "miC", "qyC", "miB", "qyB", "Eyk", "mjg", "tbr", "hyk", "Eyc", "mja", "hyc", "qza", "mjD", "hyE", "EyC", "hyC", "EyB", "Ezg", "mjr", "hzg", "Eza",
|
|
|
181 |
"hza", "EzD", "hzD", "Ezr", "ytc", "zgq", "grw", "ytE", "zgn", "gny", "ytC", "glz", "ytB", "wlc", "ycq", "xnc", "wlE", "ycn", "xnE", "ytn", "xnC", "wlB", "xnB", "tDc", "wlq", "vbc", "tDE",
|
|
|
182 |
"wln", "vbE", "xnn", "vbC", "tDB", "vbB", "mbc", "tDq", "qjc", "mbE", "tDn", "qjE", "vbn", "qjC", "mbB", "qjB", "Ejc", "mbq", "gzc", "EjE", "mbn", "gzE", "qjn", "gzC", "EjB", "gzB", "Ejq",
|
|
|
183 |
"gzq", "Ejn", "gzn", "yso", "zgf", "gfy", "ysm", "gdz", "ysl", "wko", "ycf", "xlo", "ysv", "xlm", "wkl", "xll", "tBo", "wkv", "vDo", "tBm", "vDm", "tBl", "vDl", "mDo", "tBv", "qbo", "vDv",
|
|
|
184 |
"qbm", "mDl", "qbl", "Ebo", "mDv", "gjo", "Ebm", "gjm", "Ebl", "gjl", "Ebv", "gjv", "yse", "gFz", "ysd", "wke", "xku", "wkd", "xkt", "tAu", "vBu", "tAt", "vBt", "mBu", "qDu", "mBt", "qDt",
|
|
|
185 |
"EDu", "gbu", "EDt", "gbt", "ysF", "wkF", "xkh", "tAh", "vAx", "mAx", "qBx", "wek", "yFg", "zCr", "wec", "yFa", "weE", "yFD", "weC", "weB", "sqk", "wfg", "yFr", "sqc", "wfa", "sqE", "wfD",
|
|
|
186 |
"sqC", "sqB", "lik", "srg", "wfr", "lic", "sra", "liE", "srD", "liC", "liB", "Cyk", "ljg", "srr", "Cyc", "lja", "CyE", "ljD", "CyC", "CyB", "Czg", "ljr", "Cza", "CzD", "Czr", "yhc", "zaq",
|
|
|
187 |
"arw", "yhE", "zan", "any", "yhC", "alz", "yhB", "wdc", "yEq", "wvc", "wdE", "yEn", "wvE", "yhn", "wvC", "wdB", "wvB", "snc", "wdq", "trc", "snE", "wdn", "trE", "wvn", "trC", "snB", "trB",
|
|
|
188 |
"lbc", "snq", "njc", "lbE", "snn", "njE", "trn", "njC", "lbB", "njB", "Cjc", "lbq", "azc", "CjE", "lbn", "azE", "njn", "azC", "CjB", "azB", "Cjq", "azq", "Cjn", "azn", "zio", "irs", "rfy",
|
|
|
189 |
"zim", "inw", "rdz", "zil", "ily", "ikz", "ygo", "zaf", "afy", "yxo", "ziv", "ivy", "adz", "yxm", "ygl", "itz", "yxl", "wco", "yEf", "wto", "wcm", "xvo", "yxv", "wcl", "xvm", "wtl", "xvl",
|
|
|
190 |
"slo", "wcv", "tno", "slm", "vro", "tnm", "sll", "vrm", "tnl", "vrl", "lDo", "slv", "nbo", "lDm", "rjo", "nbm", "lDl", "rjm", "nbl", "rjl", "Cbo", "lDv", "ajo", "Cbm", "izo", "ajm", "Cbl",
|
|
|
191 |
"izm", "ajl", "izl", "Cbv", "ajv", "zie", "ifw", "rFz", "zid", "idy", "icz", "yge", "aFz", "ywu", "ygd", "ihz", "ywt", "wce", "wsu", "wcd", "xtu", "wst", "xtt", "sku", "tlu", "skt", "vnu",
|
|
|
192 |
"tlt", "vnt", "lBu", "nDu", "lBt", "rbu", "nDt", "rbt", "CDu", "abu", "CDt", "iju", "abt", "ijt", "ziF", "iFy", "iEz", "ygF", "ywh", "wcF", "wsh", "xsx", "skh", "tkx", "vlx", "lAx", "nBx",
|
|
|
193 |
"rDx", "CBx", "aDx", "ibx", "iCz", "wFc", "yCq", "wFE", "yCn", "wFC", "wFB", "sfc", "wFq", "sfE", "wFn", "sfC", "sfB", "krc", "sfq", "krE", "sfn", "krC", "krB", "Bjc", "krq", "BjE", "krn",
|
|
|
194 |
"BjC", "BjB", "Bjq", "Bjn", "yao", "zDf", "Dfy", "yam", "Ddz", "yal", "wEo", "yCf", "who", "wEm", "whm", "wEl", "whl", "sdo", "wEv", "svo", "sdm", "svm", "sdl", "svl", "kno", "sdv", "lro",
|
|
|
195 |
"knm", "lrm", "knl", "lrl", "Bbo", "knv", "Djo", "Bbm", "Djm", "Bbl", "Djl", "Bbv", "Djv", "zbe", "bfw", "npz", "zbd", "bdy", "bcz", "yae", "DFz", "yiu", "yad", "bhz", "yit", "wEe", "wgu",
|
|
|
196 |
"wEd", "wxu", "wgt", "wxt", "scu", "stu", "sct", "tvu", "stt", "tvt", "klu", "lnu", "klt", "nru", "lnt", "nrt", "BDu", "Dbu", "BDt", "bju", "Dbt", "bjt", "jfs", "rpy", "jdw", "roz", "jcy",
|
|
|
197 |
"jcj", "zbF", "bFy", "zjh", "jhy", "bEz", "jgz", "yaF", "yih", "yyx", "wEF", "wgh", "wwx", "xxx", "sch", "ssx", "ttx", "vvx", "kkx", "llx", "nnx", "rrx", "BBx", "DDx", "bbx", "jFw", "rmz",
|
|
|
198 |
"jEy", "jEj", "bCz", "jaz", "jCy", "jCj", "jBj", "wCo", "wCm", "wCl", "sFo", "wCv", "sFm", "sFl", "kfo", "sFv", "kfm", "kfl", "Aro", "kfv", "Arm", "Arl", "Arv", "yDe", "Bpz", "yDd", "wCe",
|
|
|
199 |
"wau", "wCd", "wat", "sEu", "shu", "sEt", "sht", "kdu", "kvu", "kdt", "kvt", "Anu", "Bru", "Ant", "Brt", "zDp", "Dpy", "Doz", "yDF", "ybh", "wCF", "wah", "wix", "sEh", "sgx", "sxx", "kcx",
|
|
|
200 |
"ktx", "lvx", "Alx", "Bnx", "Drx", "bpw", "nuz", "boy", "boj", "Dmz", "bqz", "jps", "ruy", "jow", "ruj", "joi", "job", "bmy", "jqy", "bmj", "jqj", "jmw", "rtj", "jmi", "jmb", "blj", "jnj",
|
|
|
201 |
"jli", "jlb", "jkr", "sCu", "sCt", "kFu", "kFt", "Afu", "Aft", "wDh", "sCh", "sax", "kEx", "khx", "Adx", "Avx", "Buz", "Duy", "Duj", "buw", "nxj", "bui", "bub", "Dtj", "bvj", "jus", "rxi",
|
|
|
202 |
"jug", "rxb", "jua", "juD", "bti", "jvi", "btb", "jvb", "jtg", "rwr", "jta", "jtD", "bsr", "jtr", "jsq", "jsn", "Bxj", "Dxi", "Dxb", "bxg", "nyr", "bxa", "bxD", "Dwr", "bxr", "bwq", "bwn",
|
|
|
203 |
"pjk", "urw", "ejA", "pbs", "uny", "ebk", "pDw", "ulz", "eDs", "pBy", "eBw", "zfc", "fjk", "prw", "zfE", "fbs", "pny", "zfC", "fDw", "plz", "zfB", "fBy", "yrc", "zfq", "frw", "yrE", "zfn",
|
|
|
204 |
"fny", "yrC", "flz", "yrB", "xjc", "yrq", "xjE", "yrn", "xjC", "xjB", "uzc", "xjq", "uzE", "xjn", "uzC", "uzB", "pzc", "uzq", "pzE", "uzn", "pzC", "djA", "ors", "ufy", "dbk", "onw", "udz",
|
|
|
205 |
"dDs", "oly", "dBw", "okz", "dAy", "zdo", "drs", "ovy", "zdm", "dnw", "otz", "zdl", "dly", "dkz", "yno", "zdv", "dvy", "ynm", "dtz", "ynl", "xbo", "ynv", "xbm", "xbl", "ujo", "xbv", "ujm",
|
|
|
206 |
"ujl", "ozo", "ujv", "ozm", "ozl", "crk", "ofw", "uFz", "cns", "ody", "clw", "ocz", "cky", "ckj", "zcu", "cvw", "ohz", "zct", "cty", "csz", "ylu", "cxz", "ylt", "xDu", "xDt", "ubu", "ubt",
|
|
|
207 |
"oju", "ojt", "cfs", "oFy", "cdw", "oEz", "ccy", "ccj", "zch", "chy", "cgz", "ykx", "xBx", "uDx", "cFw", "oCz", "cEy", "cEj", "caz", "cCy", "cCj", "FjA", "mrs", "tfy", "Fbk", "mnw", "tdz",
|
|
|
208 |
"FDs", "mly", "FBw", "mkz", "FAy", "zFo", "Frs", "mvy", "zFm", "Fnw", "mtz", "zFl", "Fly", "Fkz", "yfo", "zFv", "Fvy", "yfm", "Ftz", "yfl", "wro", "yfv", "wrm", "wrl", "tjo", "wrv", "tjm",
|
|
|
209 |
"tjl", "mzo", "tjv", "mzm", "mzl", "qrk", "vfw", "xpz", "hbA", "qns", "vdy", "hDk", "qlw", "vcz", "hBs", "qky", "hAw", "qkj", "hAi", "Erk", "mfw", "tFz", "hrk", "Ens", "mdy", "hns", "qty",
|
|
|
210 |
"mcz", "hlw", "Eky", "hky", "Ekj", "hkj", "zEu", "Evw", "mhz", "zhu", "zEt", "hvw", "Ety", "zht", "hty", "Esz", "hsz", "ydu", "Exz", "yvu", "ydt", "hxz", "yvt", "wnu", "xru", "wnt", "xrt",
|
|
|
211 |
"tbu", "vju", "tbt", "vjt", "mju", "mjt", "grA", "qfs", "vFy", "gnk", "qdw", "vEz", "gls", "qcy", "gkw", "qcj", "gki", "gkb", "Efs", "mFy", "gvs", "Edw", "mEz", "gtw", "qgz", "gsy", "Ecj",
|
|
|
212 |
"gsj", "zEh", "Ehy", "zgx", "gxy", "Egz", "gwz", "ycx", "ytx", "wlx", "xnx", "tDx", "vbx", "mbx", "gfk", "qFw", "vCz", "gds", "qEy", "gcw", "qEj", "gci", "gcb", "EFw", "mCz", "ghw", "EEy",
|
|
|
213 |
"ggy", "EEj", "ggj", "Eaz", "giz", "gFs", "qCy", "gEw", "qCj", "gEi", "gEb", "ECy", "gay", "ECj", "gaj", "gCw", "qBj", "gCi", "gCb", "EBj", "gDj", "gBi", "gBb", "Crk", "lfw", "spz", "Cns",
|
|
|
214 |
"ldy", "Clw", "lcz", "Cky", "Ckj", "zCu", "Cvw", "lhz", "zCt", "Cty", "Csz", "yFu", "Cxz", "yFt", "wfu", "wft", "sru", "srt", "lju", "ljt", "arA", "nfs", "tpy", "ank", "ndw", "toz", "als",
|
|
|
215 |
"ncy", "akw", "ncj", "aki", "akb", "Cfs", "lFy", "avs", "Cdw", "lEz", "atw", "ngz", "asy", "Ccj", "asj", "zCh", "Chy", "zax", "axy", "Cgz", "awz", "yEx", "yhx", "wdx", "wvx", "snx", "trx",
|
|
|
216 |
"lbx", "rfk", "vpw", "xuz", "inA", "rds", "voy", "ilk", "rcw", "voj", "iks", "rci", "ikg", "rcb", "ika", "afk", "nFw", "tmz", "ivk", "ads", "nEy", "its", "rgy", "nEj", "isw", "aci", "isi",
|
|
|
217 |
"acb", "isb", "CFw", "lCz", "ahw", "CEy", "ixw", "agy", "CEj", "iwy", "agj", "iwj", "Caz", "aiz", "iyz", "ifA", "rFs", "vmy", "idk", "rEw", "vmj", "ics", "rEi", "icg", "rEb", "ica", "icD",
|
|
|
218 |
"aFs", "nCy", "ihs", "aEw", "nCj", "igw", "raj", "igi", "aEb", "igb", "CCy", "aay", "CCj", "iiy", "aaj", "iij", "iFk", "rCw", "vlj", "iEs", "rCi", "iEg", "rCb", "iEa", "iED", "aCw", "nBj",
|
|
|
219 |
"iaw", "aCi", "iai", "aCb", "iab", "CBj", "aDj", "ibj", "iCs", "rBi", "iCg", "rBb", "iCa", "iCD", "aBi", "iDi", "aBb", "iDb", "iBg", "rAr", "iBa", "iBD", "aAr", "iBr", "iAq", "iAn", "Bfs",
|
|
|
220 |
"kpy", "Bdw", "koz", "Bcy", "Bcj", "Bhy", "Bgz", "yCx", "wFx", "sfx", "krx", "Dfk", "lpw", "suz", "Dds", "loy", "Dcw", "loj", "Dci", "Dcb", "BFw", "kmz", "Dhw", "BEy", "Dgy", "BEj", "Dgj",
|
|
|
221 |
"Baz", "Diz", "bfA", "nps", "tuy", "bdk", "now", "tuj", "bcs", "noi", "bcg", "nob", "bca", "bcD", "DFs", "lmy", "bhs", "DEw", "lmj", "bgw", "DEi", "bgi", "DEb", "bgb", "BCy", "Day", "BCj",
|
|
|
222 |
"biy", "Daj", "bij", "rpk", "vuw", "xxj", "jdA", "ros", "vui", "jck", "rog", "vub", "jcc", "roa", "jcE", "roD", "jcC", "bFk", "nmw", "ttj", "jhk", "bEs", "nmi", "jgs", "rqi", "nmb", "jgg",
|
|
|
223 |
"bEa", "jga", "bED", "jgD", "DCw", "llj", "baw", "DCi", "jiw", "bai", "DCb", "jii", "bab", "jib", "BBj", "DDj", "bbj", "jjj", "jFA", "rms", "vti", "jEk", "rmg", "vtb", "jEc", "rma", "jEE",
|
|
|
224 |
"rmD", "jEC", "jEB", "bCs", "nli", "jas", "bCg", "nlb", "jag", "rnb", "jaa", "bCD", "jaD", "DBi", "bDi", "DBb", "jbi", "bDb", "jbb", "jCk", "rlg", "vsr", "jCc", "rla", "jCE", "rlD", "jCC",
|
|
|
225 |
"jCB", "bBg", "nkr", "jDg", "bBa", "jDa", "bBD", "jDD", "DAr", "bBr", "jDr", "jBc", "rkq", "jBE", "rkn", "jBC", "jBB", "bAq", "jBq", "bAn", "jBn", "jAo", "rkf", "jAm", "jAl", "bAf", "jAv",
|
|
|
226 |
"Apw", "kez", "Aoy", "Aoj", "Aqz", "Bps", "kuy", "Bow", "kuj", "Boi", "Bob", "Amy", "Bqy", "Amj", "Bqj", "Dpk", "luw", "sxj", "Dos", "lui", "Dog", "lub", "Doa", "DoD", "Bmw", "ktj", "Dqw",
|
|
|
227 |
"Bmi", "Dqi", "Bmb", "Dqb", "Alj", "Bnj", "Drj", "bpA", "nus", "txi", "bok", "nug", "txb", "boc", "nua", "boE", "nuD", "boC", "boB", "Dms", "lti", "bqs", "Dmg", "ltb", "bqg", "nvb", "bqa",
|
|
|
228 |
"DmD", "bqD", "Bli", "Dni", "Blb", "bri", "Dnb", "brb", "ruk", "vxg", "xyr", "ruc", "vxa", "ruE", "vxD", "ruC", "ruB", "bmk", "ntg", "twr", "jqk", "bmc", "nta", "jqc", "rva", "ntD", "jqE",
|
|
|
229 |
"bmC", "jqC", "bmB", "jqB", "Dlg", "lsr", "bng", "Dla", "jrg", "bna", "DlD", "jra", "bnD", "jrD", "Bkr", "Dlr", "bnr", "jrr", "rtc", "vwq", "rtE", "vwn", "rtC", "rtB", "blc", "nsq", "jnc",
|
|
|
230 |
"blE", "nsn", "jnE", "rtn", "jnC", "blB", "jnB", "Dkq", "blq", "Dkn", "jnq", "bln", "jnn", "rso", "vwf", "rsm", "rsl", "bko", "nsf", "jlo", "bkm", "jlm", "bkl", "jll", "Dkf", "bkv", "jlv",
|
|
|
231 |
"rse", "rsd", "bke", "jku", "bkd", "jkt", "Aey", "Aej", "Auw", "khj", "Aui", "Aub", "Adj", "Avj", "Bus", "kxi", "Bug", "kxb", "Bua", "BuD", "Ati", "Bvi", "Atb", "Bvb", "Duk", "lxg", "syr",
|
|
|
232 |
"Duc", "lxa", "DuE", "lxD", "DuC", "DuB", "Btg", "kwr", "Dvg", "lxr", "Dva", "BtD", "DvD", "Asr", "Btr", "Dvr", "nxc", "tyq", "nxE", "tyn", "nxC", "nxB", "Dtc", "lwq", "bvc", "nxq", "lwn",
|
|
|
233 |
"bvE", "DtC", "bvC", "DtB", "bvB", "Bsq", "Dtq", "Bsn", "bvq", "Dtn", "bvn", "vyo", "xzf", "vym", "vyl", "nwo", "tyf", "rxo", "nwm", "rxm", "nwl", "rxl", "Dso", "lwf", "bto", "Dsm", "jvo",
|
|
|
234 |
"btm", "Dsl", "jvm", "btl", "jvl", "Bsf", "Dsv", "btv", "jvv", "vye", "vyd", "nwe", "rwu", "nwd", "rwt", "Dse", "bsu", "Dsd", "jtu", "bst", "jtt", "vyF", "nwF", "rwh", "DsF", "bsh", "jsx",
|
|
|
235 |
"Ahi", "Ahb", "Axg", "kir", "Axa", "AxD", "Agr", "Axr", "Bxc", "kyq", "BxE", "kyn", "BxC", "BxB", "Awq", "Bxq", "Awn", "Bxn", "lyo", "szf", "lym", "lyl", "Bwo", "kyf", "Dxo", "lyv", "Dxm",
|
|
|
236 |
"Bwl", "Dxl", "Awf", "Bwv", "Dxv", "tze", "tzd", "lye", "nyu", "lyd", "nyt", "Bwe", "Dwu", "Bwd", "bxu", "Dwt", "bxt", "tzF", "lyF", "nyh", "BwF", "Dwh", "bwx", "Aiq", "Ain", "Ayo", "kjf",
|
|
|
237 |
"Aym", "Ayl", "Aif", "Ayv", "kze", "kzd", "Aye", "Byu", "Ayd", "Byt", "szp" };
|
|
|
238 |
|
|
|
239 |
private static final char[] BR_SET = { 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
|
|
|
240 |
'z', '*', '+', '-' };
|
|
|
241 |
|
|
|
242 |
private static final String[] PDF_TTF = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000",
|
|
|
243 |
"10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111", "01", "1111111101010100", "11111101000101001" };
|
|
|
244 |
|
|
|
245 |
/* Left and Right Row Address Pattern from Table 2 */
|
|
|
246 |
private static final String[] RAPLR = { "", "221311", "311311", "312211", "222211", "213211", "214111", "223111", "313111", "322111", "412111", "421111", "331111", "241111", "232111", "231211",
|
|
|
247 |
"321211", "411211", "411121", "411112", "321112", "312112", "311212", "311221", "311131", "311122", "311113", "221113", "221122", "221131", "221221", "222121", "312121", "321121",
|
|
|
248 |
"231121", "231112", "222112", "213112", "212212", "212221", "212131", "212122", "212113", "211213", "211123", "211132", "211141", "211231", "211222", "211312", "211321", "211411",
|
|
|
249 |
"212311" };
|
|
|
250 |
|
|
|
251 |
/* Centre Row Address Pattern from Table 2 */
|
|
|
252 |
private static final String[] RAPC = { "", "112231", "121231", "122131", "131131", "131221", "132121", "141121", "141211", "142111", "133111", "132211", "131311", "122311", "123211", "124111",
|
|
|
253 |
"115111", "114211", "114121", "123121", "123112", "122212", "122221", "121321", "121411", "112411", "113311", "113221", "113212", "113122", "122122", "131122", "131113", "122113",
|
|
|
254 |
"113113", "112213", "112222", "112312", "112321", "111421", "111331", "111322", "111232", "111223", "111133", "111124", "111214", "112114", "121114", "121123", "121132", "112132",
|
|
|
255 |
"112141" };
|
|
|
256 |
|
|
|
257 |
private static final int[] MICRO_VARIANTS = { 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, 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23,
|
|
|
258 |
26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 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,
|
|
|
259 |
26, 32, 38, 44, 50, 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 };
|
|
|
260 |
|
|
|
261 |
/* rows, columns, error codewords, k-offset */
|
|
|
262 |
/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */
|
|
|
263 |
private static final int[] MICROCOEFFS = {
|
|
|
264 |
/* k = 7 */
|
|
|
265 |
76, 925, 537, 597, 784, 691, 437,
|
|
|
266 |
/* k = 8 */
|
|
|
267 |
237, 308, 436, 284, 646, 653, 428, 379,
|
|
|
268 |
/* k = 9 */
|
|
|
269 |
567, 527, 622, 257, 289, 362, 501, 441, 205,
|
|
|
270 |
/* k = 10 */
|
|
|
271 |
377, 457, 64, 244, 826, 841, 818, 691, 266, 612,
|
|
|
272 |
/* k = 11 */
|
|
|
273 |
462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904,
|
|
|
274 |
/* k = 12 */
|
|
|
275 |
597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851,
|
|
|
276 |
/* k = 13 */
|
|
|
277 |
764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692,
|
|
|
278 |
/* k = 14 */
|
|
|
279 |
669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215,
|
|
|
280 |
/* k = 15 */
|
|
|
281 |
460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642,
|
|
|
282 |
/* k = 16 */
|
|
|
283 |
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
|
|
|
284 |
/* k = 18 */
|
|
|
285 |
279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756, 760, 573,
|
|
|
286 |
/* k = 21 */
|
|
|
287 |
108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691, 347, 165, 193, 259, 568,
|
|
|
288 |
/* k = 26 */
|
|
|
289 |
443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893, 699, 245, 441, 454, 325, 858, 131, 847, 764, 169,
|
|
|
290 |
/* k = 32 */
|
|
|
291 |
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
|
|
|
292 |
/* k = 38 */
|
|
|
293 |
234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684, 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771, 554, 289, 231, 125, 117, 518,
|
|
|
294 |
/* k = 44 */
|
|
|
295 |
476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405, 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213, 31, 560, 231, 758, 103, 271, 572,
|
|
|
296 |
436, 339, 730, 82, 285,
|
|
|
297 |
/* k = 50 */
|
|
|
298 |
923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303, 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26, 579, 623, 766, 146, 10, 739, 246,
|
|
|
299 |
127, 71, 244, 211, 477, 920, 876, 427, 820, 718, 435 };
|
|
|
300 |
|
|
|
301 |
/*
|
|
|
302 |
* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables
|
|
|
303 |
* 10, 11 and 12
|
|
|
304 |
*/
|
|
|
305 |
private static final int[] RAP_TABLE = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
306 |
0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 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,
|
|
|
307 |
33, 17, 37, 47, 49, 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 };
|
|
|
308 |
|
|
|
309 |
private String binary_string;
|
|
|
310 |
private int ecc;
|
|
|
311 |
private LinearEncoding symbology = LinearEncoding.CODE_128;
|
|
|
312 |
private String general_field;
|
|
|
313 |
private GeneralFieldMode[] general_field_type;
|
|
|
314 |
private int cc_width;
|
|
|
315 |
private final int[][] pwr928 = new int[69][7];
|
|
|
316 |
private final int[] codeWords = new int[180];
|
|
|
317 |
private int codeWordCount;
|
|
|
318 |
private final int[] bitStr = new int[13];
|
|
|
319 |
private int[] inputData;
|
|
|
320 |
private CompositeMode cc_mode;
|
|
|
321 |
private String linearContent;
|
|
|
322 |
private CompositeMode userPreferredMode = CompositeMode.CC_A;
|
|
|
323 |
private int target_bitsize;
|
|
|
324 |
private int remainder;
|
|
|
325 |
private int linearWidth; // Width of Code 128 linear
|
|
|
326 |
|
|
|
327 |
public Composite() {
|
|
|
328 |
this.inputDataType = Symbol.DataType.GS1;
|
|
|
329 |
}
|
|
|
330 |
|
|
|
331 |
@Override
|
|
|
332 |
public void setDataType(final DataType dataType) {
|
|
|
333 |
if (dataType != Symbol.DataType.GS1) {
|
|
|
334 |
throw new IllegalArgumentException("Only GS1 data type is supported for GS1 Composite symbology.");
|
|
|
335 |
}
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
@Override
|
|
|
339 |
protected boolean gs1Supported() {
|
|
|
340 |
return true;
|
|
|
341 |
}
|
|
|
342 |
|
|
|
343 |
/**
|
|
|
344 |
* Set the type of linear component included in the composite symbol, this will determine how
|
|
|
345 |
* the lower part of the symbol is encoded.
|
|
|
346 |
*
|
|
|
347 |
* @param linearSymbology The symbology of the linear component
|
|
|
348 |
*/
|
|
|
349 |
public void setSymbology(final LinearEncoding linearSymbology) {
|
|
|
350 |
this.symbology = linearSymbology;
|
|
|
351 |
}
|
|
|
352 |
|
|
|
353 |
/**
|
|
|
354 |
* Returns the type of linear component included in the composite symbol.
|
|
|
355 |
*
|
|
|
356 |
* @return the type of linear component included in the composite symbol
|
|
|
357 |
*/
|
|
|
358 |
public LinearEncoding getSymbology() {
|
|
|
359 |
return this.symbology;
|
|
|
360 |
}
|
|
|
361 |
|
|
|
362 |
/**
|
|
|
363 |
* Set the data to be encoded in the linear component of the composite symbol.
|
|
|
364 |
*
|
|
|
365 |
* @param linearContent the linear data in GS1 format
|
|
|
366 |
*/
|
|
|
367 |
public void setLinearContent(final String linearContent) {
|
|
|
368 |
this.linearContent = linearContent;
|
|
|
369 |
}
|
|
|
370 |
|
|
|
371 |
/**
|
|
|
372 |
* Returns the data encoded in the linear component of the composite symbol.
|
|
|
373 |
*
|
|
|
374 |
* @return the data encoded in the linear component of the composite symbol
|
|
|
375 |
*/
|
|
|
376 |
public String getLinearContent() {
|
|
|
377 |
return this.linearContent;
|
|
|
378 |
}
|
|
|
379 |
|
|
|
380 |
/**
|
|
|
381 |
* Set the preferred encoding method for the 2D component of the composite symbol. This value
|
|
|
382 |
* may be ignored if the amount of data supplied is too big for the selected encoding. Mode CC-C
|
|
|
383 |
* can only be used with a Code 128 linear component.
|
|
|
384 |
*
|
|
|
385 |
* @param userMode Preferred mode
|
|
|
386 |
*/
|
|
|
387 |
public void setPreferredMode(final CompositeMode userMode) {
|
|
|
388 |
this.userPreferredMode = userMode;
|
|
|
389 |
}
|
|
|
390 |
|
|
|
391 |
/**
|
|
|
392 |
* Returns the preferred encoding method for the 2D component of the composite symbol.
|
|
|
393 |
*
|
|
|
394 |
* @return the preferred encoding method for the 2D component of the composite symbol
|
|
|
395 |
*/
|
|
|
396 |
public CompositeMode getPreferredMode() {
|
|
|
397 |
return this.userPreferredMode;
|
|
|
398 |
}
|
|
|
399 |
|
|
|
400 |
@Override
|
|
|
401 |
protected void encode() {
|
|
|
402 |
|
|
|
403 |
List<Rectangle2D.Double> linear_rect;
|
|
|
404 |
List<TextBox> linear_txt;
|
|
|
405 |
final List<Rectangle2D.Double> combine_rect = new ArrayList<>();
|
|
|
406 |
final List<TextBox> combine_txt = new ArrayList<>();
|
|
|
407 |
String linear_encodeInfo;
|
|
|
408 |
int linear_height;
|
|
|
409 |
int top_shift = 0; // 2D component x-coordinate shift
|
|
|
410 |
int bottom_shift = 0; // linear component x-coordinate shift
|
|
|
411 |
this.linearWidth = 0;
|
|
|
412 |
|
|
|
413 |
if (this.linearContent.isEmpty()) {
|
|
|
414 |
throw new OkapiException("No linear data set");
|
|
|
415 |
}
|
|
|
416 |
|
|
|
417 |
// Manage composite component encoding first
|
|
|
418 |
encodeComposite();
|
|
|
419 |
|
|
|
420 |
// Then encode linear component
|
|
|
421 |
switch (this.symbology) {
|
|
|
422 |
case UPCA:
|
|
|
423 |
final Upc upca = new Upc();
|
|
|
424 |
upca.setMode(Upc.Mode.UPCA);
|
|
|
425 |
upca.setLinkageFlag(true);
|
|
|
426 |
upca.setContent(this.linearContent);
|
|
|
427 |
linear_rect = upca.rectangles;
|
|
|
428 |
linear_txt = upca.texts;
|
|
|
429 |
linear_height = upca.symbol_height;
|
|
|
430 |
linear_encodeInfo = upca.getEncodeInfo();
|
|
|
431 |
bottom_shift = 6;
|
|
|
432 |
top_shift = 3;
|
|
|
433 |
break;
|
|
|
434 |
case UPCE:
|
|
|
435 |
final Upc upce = new Upc();
|
|
|
436 |
upce.setMode(Upc.Mode.UPCE);
|
|
|
437 |
upce.setLinkageFlag(true);
|
|
|
438 |
upce.setContent(this.linearContent);
|
|
|
439 |
linear_rect = upce.rectangles;
|
|
|
440 |
linear_txt = upce.texts;
|
|
|
441 |
linear_height = upce.symbol_height;
|
|
|
442 |
linear_encodeInfo = upce.getEncodeInfo();
|
|
|
443 |
bottom_shift = 6;
|
|
|
444 |
top_shift = 3;
|
|
|
445 |
break;
|
|
|
446 |
case EAN:
|
|
|
447 |
final Ean ean = new Ean();
|
|
|
448 |
if (eanCalculateVersion() == 8) {
|
|
|
449 |
ean.setMode(Ean.Mode.EAN8);
|
|
|
450 |
bottom_shift = 14;
|
|
|
451 |
} else {
|
|
|
452 |
ean.setMode(Ean.Mode.EAN13);
|
|
|
453 |
bottom_shift = 6;
|
|
|
454 |
top_shift = 3;
|
|
|
455 |
}
|
|
|
456 |
ean.setLinkageFlag(true);
|
|
|
457 |
ean.setContent(this.linearContent);
|
|
|
458 |
linear_rect = ean.rectangles;
|
|
|
459 |
linear_txt = ean.texts;
|
|
|
460 |
linear_height = ean.symbol_height;
|
|
|
461 |
linear_encodeInfo = ean.getEncodeInfo();
|
|
|
462 |
break;
|
|
|
463 |
case CODE_128:
|
|
|
464 |
final Code128 code128 = new Code128();
|
|
|
465 |
switch (this.cc_mode) {
|
|
|
466 |
case CC_A:
|
|
|
467 |
code128.setCca();
|
|
|
468 |
break;
|
|
|
469 |
case CC_B:
|
|
|
470 |
code128.setCcb();
|
|
|
471 |
break;
|
|
|
472 |
case CC_C:
|
|
|
473 |
code128.setCcc();
|
|
|
474 |
bottom_shift = 7;
|
|
|
475 |
break;
|
|
|
476 |
}
|
|
|
477 |
code128.setDataType(Symbol.DataType.GS1);
|
|
|
478 |
code128.setContent(this.linearContent);
|
|
|
479 |
this.linearWidth = code128.symbol_width;
|
|
|
480 |
linear_rect = code128.rectangles;
|
|
|
481 |
linear_txt = code128.texts;
|
|
|
482 |
linear_height = code128.symbol_height;
|
|
|
483 |
linear_encodeInfo = code128.getEncodeInfo();
|
|
|
484 |
break;
|
|
|
485 |
case DATABAR_14:
|
|
|
486 |
final DataBar14 dataBar14 = new DataBar14();
|
|
|
487 |
dataBar14.setLinkageFlag(true);
|
|
|
488 |
dataBar14.setMode(Mode.LINEAR);
|
|
|
489 |
dataBar14.setContent(this.linearContent);
|
|
|
490 |
linear_rect = dataBar14.rectangles;
|
|
|
491 |
linear_txt = dataBar14.texts;
|
|
|
492 |
linear_height = dataBar14.symbol_height;
|
|
|
493 |
linear_encodeInfo = dataBar14.getEncodeInfo();
|
|
|
494 |
bottom_shift = 4;
|
|
|
495 |
break;
|
|
|
496 |
case DATABAR_14_STACK_OMNI:
|
|
|
497 |
final DataBar14 dataBar14SO = new DataBar14();
|
|
|
498 |
dataBar14SO.setLinkageFlag(true);
|
|
|
499 |
dataBar14SO.setMode(Mode.OMNI);
|
|
|
500 |
dataBar14SO.setContent(this.linearContent);
|
|
|
501 |
linear_rect = dataBar14SO.rectangles;
|
|
|
502 |
linear_txt = dataBar14SO.texts;
|
|
|
503 |
linear_height = dataBar14SO.symbol_height;
|
|
|
504 |
linear_encodeInfo = dataBar14SO.getEncodeInfo();
|
|
|
505 |
top_shift = 1;
|
|
|
506 |
break;
|
|
|
507 |
case DATABAR_14_STACK:
|
|
|
508 |
final DataBar14 dataBar14S = new DataBar14();
|
|
|
509 |
dataBar14S.setLinkageFlag(true);
|
|
|
510 |
dataBar14S.setMode(Mode.STACKED);
|
|
|
511 |
dataBar14S.setContent(this.linearContent);
|
|
|
512 |
linear_rect = dataBar14S.rectangles;
|
|
|
513 |
linear_txt = dataBar14S.texts;
|
|
|
514 |
linear_height = dataBar14S.symbol_height;
|
|
|
515 |
linear_encodeInfo = dataBar14S.getEncodeInfo();
|
|
|
516 |
top_shift = 1;
|
|
|
517 |
break;
|
|
|
518 |
case DATABAR_LIMITED:
|
|
|
519 |
final DataBarLimited dataBarLimited = new DataBarLimited();
|
|
|
520 |
dataBarLimited.setLinkageFlag();
|
|
|
521 |
dataBarLimited.setContent(this.linearContent);
|
|
|
522 |
linear_rect = dataBarLimited.rectangles;
|
|
|
523 |
linear_txt = dataBarLimited.texts;
|
|
|
524 |
linear_height = dataBarLimited.symbol_height;
|
|
|
525 |
linear_encodeInfo = dataBarLimited.getEncodeInfo();
|
|
|
526 |
top_shift = 1;
|
|
|
527 |
bottom_shift = 10;
|
|
|
528 |
break;
|
|
|
529 |
case DATABAR_EXPANDED:
|
|
|
530 |
final DataBarExpanded dataBarExpanded = new DataBarExpanded();
|
|
|
531 |
dataBarExpanded.setLinkageFlag(true);
|
|
|
532 |
dataBarExpanded.setStacked(false);
|
|
|
533 |
dataBarExpanded.setContent(this.linearContent);
|
|
|
534 |
linear_rect = dataBarExpanded.rectangles;
|
|
|
535 |
linear_txt = dataBarExpanded.texts;
|
|
|
536 |
linear_height = dataBarExpanded.symbol_height;
|
|
|
537 |
linear_encodeInfo = dataBarExpanded.getEncodeInfo();
|
|
|
538 |
top_shift = 2;
|
|
|
539 |
break;
|
|
|
540 |
case DATABAR_EXPANDED_STACK:
|
|
|
541 |
final DataBarExpanded dataBarExpandedS = new DataBarExpanded();
|
|
|
542 |
dataBarExpandedS.setLinkageFlag(true);
|
|
|
543 |
dataBarExpandedS.setStacked(true);
|
|
|
544 |
dataBarExpandedS.setContent(this.linearContent);
|
|
|
545 |
linear_rect = dataBarExpandedS.rectangles;
|
|
|
546 |
linear_txt = dataBarExpandedS.texts;
|
|
|
547 |
linear_height = dataBarExpandedS.symbol_height;
|
|
|
548 |
linear_encodeInfo = dataBarExpandedS.getEncodeInfo();
|
|
|
549 |
top_shift = 2;
|
|
|
550 |
break;
|
|
|
551 |
default:
|
|
|
552 |
throw new OkapiException("Linear symbol not recognised");
|
|
|
553 |
}
|
|
|
554 |
|
|
|
555 |
if (this.cc_mode == CompositeMode.CC_C && this.symbology == LinearEncoding.CODE_128) {
|
|
|
556 |
/*
|
|
|
557 |
* Width of composite component depends on width of linear component, so recalculate.
|
|
|
558 |
*/
|
|
|
559 |
this.row_count = 0;
|
|
|
560 |
this.rectangles.clear();
|
|
|
561 |
this.symbol_height = 0;
|
|
|
562 |
this.symbol_width = 0;
|
|
|
563 |
this.encodeInfo.setLength(0);
|
|
|
564 |
encodeComposite();
|
|
|
565 |
}
|
|
|
566 |
|
|
|
567 |
if (this.cc_mode != CompositeMode.CC_C && this.symbology == LinearEncoding.CODE_128) {
|
|
|
568 |
if (this.linearWidth > this.symbol_width) {
|
|
|
569 |
top_shift = (this.linearWidth - this.symbol_width) / 2;
|
|
|
570 |
}
|
|
|
571 |
}
|
|
|
572 |
|
|
|
573 |
for (final Rectangle2D.Double orig : this.rectangles) {
|
|
|
574 |
combine_rect.add(new Rectangle2D.Double(orig.x + top_shift, orig.y, orig.width, orig.height));
|
|
|
575 |
}
|
|
|
576 |
|
|
|
577 |
for (final Rectangle2D.Double orig : linear_rect) {
|
|
|
578 |
combine_rect.add(new Rectangle2D.Double(orig.x + bottom_shift, orig.y + this.symbol_height, orig.width, orig.height));
|
|
|
579 |
}
|
|
|
580 |
|
|
|
581 |
int max_x = 0;
|
|
|
582 |
for (final Rectangle2D.Double rect : combine_rect) {
|
|
|
583 |
if (rect.x + rect.width > max_x) {
|
|
|
584 |
max_x = (int) Math.ceil(rect.x + rect.width);
|
|
|
585 |
}
|
|
|
586 |
}
|
|
|
587 |
|
|
|
588 |
for (final TextBox orig : linear_txt) {
|
|
|
589 |
combine_txt.add(new TextBox(orig.x + bottom_shift, orig.y + this.symbol_height, orig.width, orig.text, this.humanReadableAlignment));
|
|
|
590 |
}
|
|
|
591 |
|
|
|
592 |
this.rectangles = combine_rect;
|
|
|
593 |
this.texts = combine_txt;
|
|
|
594 |
this.symbol_height += linear_height;
|
|
|
595 |
this.symbol_width = max_x;
|
|
|
596 |
info(linear_encodeInfo);
|
|
|
597 |
}
|
|
|
598 |
|
|
|
599 |
private void encodeComposite() {
|
|
|
600 |
|
|
|
601 |
if (this.content.length() > 2990) {
|
|
|
602 |
throw new OkapiException("2D component input data too long");
|
|
|
603 |
}
|
|
|
604 |
|
|
|
605 |
this.cc_mode = this.userPreferredMode;
|
|
|
606 |
|
|
|
607 |
if (this.cc_mode == CompositeMode.CC_C && this.symbology != LinearEncoding.CODE_128) {
|
|
|
608 |
/* CC-C can only be used with a GS1-128 linear part */
|
|
|
609 |
throw new OkapiException("Invalid mode (CC-C only valid with GS1-128 linear component)");
|
|
|
610 |
}
|
|
|
611 |
|
|
|
612 |
switch (this.symbology) {
|
|
|
613 |
/* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
|
|
|
614 |
case EAN:
|
|
|
615 |
if (eanCalculateVersion() == 8) {
|
|
|
616 |
this.cc_width = 3;
|
|
|
617 |
} else {
|
|
|
618 |
this.cc_width = 4;
|
|
|
619 |
}
|
|
|
620 |
break;
|
|
|
621 |
case UPCE:
|
|
|
622 |
case DATABAR_14_STACK_OMNI:
|
|
|
623 |
case DATABAR_14_STACK:
|
|
|
624 |
this.cc_width = 2;
|
|
|
625 |
break;
|
|
|
626 |
case DATABAR_LIMITED:
|
|
|
627 |
this.cc_width = 3;
|
|
|
628 |
break;
|
|
|
629 |
case CODE_128:
|
|
|
630 |
case DATABAR_14:
|
|
|
631 |
case DATABAR_EXPANDED:
|
|
|
632 |
case UPCA:
|
|
|
633 |
case DATABAR_EXPANDED_STACK:
|
|
|
634 |
this.cc_width = 4;
|
|
|
635 |
break;
|
|
|
636 |
}
|
|
|
637 |
|
|
|
638 |
infoLine("Composite Width: " + this.cc_width);
|
|
|
639 |
|
|
|
640 |
if (this.cc_mode == CompositeMode.CC_A && !cc_binary_string()) {
|
|
|
641 |
this.cc_mode = CompositeMode.CC_B;
|
|
|
642 |
}
|
|
|
643 |
|
|
|
644 |
if (this.cc_mode == CompositeMode.CC_B) { /*
|
|
|
645 |
* If the data didn't fit into CC-A it is
|
|
|
646 |
* recalculated for CC-B
|
|
|
647 |
*/
|
|
|
648 |
if (!cc_binary_string()) {
|
|
|
649 |
if (this.symbology != LinearEncoding.CODE_128) {
|
|
|
650 |
throw new OkapiException("Input too long");
|
|
|
651 |
} else {
|
|
|
652 |
this.cc_mode = CompositeMode.CC_C;
|
|
|
653 |
}
|
|
|
654 |
}
|
|
|
655 |
}
|
|
|
656 |
|
|
|
657 |
if (this.cc_mode == CompositeMode.CC_C) {
|
|
|
658 |
/*
|
|
|
659 |
* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for
|
|
|
660 |
* CC-C
|
|
|
661 |
*/
|
|
|
662 |
if (!cc_binary_string()) {
|
|
|
663 |
throw new OkapiException("Input too long");
|
|
|
664 |
}
|
|
|
665 |
}
|
|
|
666 |
|
|
|
667 |
switch (this.cc_mode) { /* Note that ecc_level is only relevant to CC-C */
|
|
|
668 |
case CC_A:
|
|
|
669 |
cc_a();
|
|
|
670 |
infoLine("Composite Type: CC-A");
|
|
|
671 |
break;
|
|
|
672 |
case CC_B:
|
|
|
673 |
cc_b();
|
|
|
674 |
infoLine("Composite Type: CC-B");
|
|
|
675 |
break;
|
|
|
676 |
case CC_C:
|
|
|
677 |
cc_c();
|
|
|
678 |
infoLine("Composite Type: CC-C");
|
|
|
679 |
break;
|
|
|
680 |
}
|
|
|
681 |
|
|
|
682 |
super.plotSymbol();
|
|
|
683 |
}
|
|
|
684 |
|
|
|
685 |
@Override
|
|
|
686 |
protected void plotSymbol() {
|
|
|
687 |
// empty
|
|
|
688 |
}
|
|
|
689 |
|
|
|
690 |
private int eanCalculateVersion() {
|
|
|
691 |
/* Determine if EAN-8 or EAN-13 is being used */
|
|
|
692 |
|
|
|
693 |
int length = 0;
|
|
|
694 |
int i;
|
|
|
695 |
boolean latch;
|
|
|
696 |
|
|
|
697 |
latch = true;
|
|
|
698 |
for (i = 0; i < this.linearContent.length(); i++) {
|
|
|
699 |
if (this.linearContent.charAt(i) >= '0' && this.linearContent.charAt(i) <= '9') {
|
|
|
700 |
if (latch) {
|
|
|
701 |
length++;
|
|
|
702 |
}
|
|
|
703 |
} else {
|
|
|
704 |
latch = false;
|
|
|
705 |
}
|
|
|
706 |
}
|
|
|
707 |
|
|
|
708 |
if (length <= 7) {
|
|
|
709 |
// EAN-8
|
|
|
710 |
return 8;
|
|
|
711 |
} else {
|
|
|
712 |
// EAN-13
|
|
|
713 |
return 13;
|
|
|
714 |
}
|
|
|
715 |
}
|
|
|
716 |
|
|
|
717 |
private boolean calculateSymbolSize() {
|
|
|
718 |
int i;
|
|
|
719 |
final int binary_length = this.binary_string.length();
|
|
|
720 |
if (this.cc_mode == CompositeMode.CC_A) {
|
|
|
721 |
/* CC-A 2D component - calculate remaining space */
|
|
|
722 |
switch (this.cc_width) {
|
|
|
723 |
case 2:
|
|
|
724 |
if (binary_length > 167) {
|
|
|
725 |
return false;
|
|
|
726 |
}
|
|
|
727 |
if (binary_length <= 167) {
|
|
|
728 |
this.target_bitsize = 167;
|
|
|
729 |
}
|
|
|
730 |
if (binary_length <= 138) {
|
|
|
731 |
this.target_bitsize = 138;
|
|
|
732 |
}
|
|
|
733 |
if (binary_length <= 118) {
|
|
|
734 |
this.target_bitsize = 118;
|
|
|
735 |
}
|
|
|
736 |
if (binary_length <= 108) {
|
|
|
737 |
this.target_bitsize = 108;
|
|
|
738 |
}
|
|
|
739 |
if (binary_length <= 88) {
|
|
|
740 |
this.target_bitsize = 88;
|
|
|
741 |
}
|
|
|
742 |
if (binary_length <= 78) {
|
|
|
743 |
this.target_bitsize = 78;
|
|
|
744 |
}
|
|
|
745 |
if (binary_length <= 59) {
|
|
|
746 |
this.target_bitsize = 59;
|
|
|
747 |
}
|
|
|
748 |
break;
|
|
|
749 |
case 3:
|
|
|
750 |
if (binary_length > 167) {
|
|
|
751 |
return false;
|
|
|
752 |
}
|
|
|
753 |
if (binary_length <= 167) {
|
|
|
754 |
this.target_bitsize = 167;
|
|
|
755 |
}
|
|
|
756 |
if (binary_length <= 138) {
|
|
|
757 |
this.target_bitsize = 138;
|
|
|
758 |
}
|
|
|
759 |
if (binary_length <= 118) {
|
|
|
760 |
this.target_bitsize = 118;
|
|
|
761 |
}
|
|
|
762 |
if (binary_length <= 98) {
|
|
|
763 |
this.target_bitsize = 98;
|
|
|
764 |
}
|
|
|
765 |
if (binary_length <= 78) {
|
|
|
766 |
this.target_bitsize = 78;
|
|
|
767 |
}
|
|
|
768 |
break;
|
|
|
769 |
case 4:
|
|
|
770 |
if (binary_length > 197) {
|
|
|
771 |
return false;
|
|
|
772 |
}
|
|
|
773 |
if (binary_length <= 197) {
|
|
|
774 |
this.target_bitsize = 197;
|
|
|
775 |
}
|
|
|
776 |
if (binary_length <= 167) {
|
|
|
777 |
this.target_bitsize = 167;
|
|
|
778 |
}
|
|
|
779 |
if (binary_length <= 138) {
|
|
|
780 |
this.target_bitsize = 138;
|
|
|
781 |
}
|
|
|
782 |
if (binary_length <= 108) {
|
|
|
783 |
this.target_bitsize = 108;
|
|
|
784 |
}
|
|
|
785 |
if (binary_length <= 78) {
|
|
|
786 |
this.target_bitsize = 78;
|
|
|
787 |
}
|
|
|
788 |
break;
|
|
|
789 |
}
|
|
|
790 |
}
|
|
|
791 |
|
|
|
792 |
if (this.cc_mode == CompositeMode.CC_B) {
|
|
|
793 |
/* CC-B 2D component - calculated from ISO/IEC 24728 Table 1 */
|
|
|
794 |
switch (this.cc_width) {
|
|
|
795 |
case 2:
|
|
|
796 |
if (binary_length > 336) {
|
|
|
797 |
return false;
|
|
|
798 |
}
|
|
|
799 |
if (binary_length <= 336) {
|
|
|
800 |
this.target_bitsize = 336;
|
|
|
801 |
}
|
|
|
802 |
if (binary_length <= 296) {
|
|
|
803 |
this.target_bitsize = 296;
|
|
|
804 |
}
|
|
|
805 |
if (binary_length <= 256) {
|
|
|
806 |
this.target_bitsize = 256;
|
|
|
807 |
}
|
|
|
808 |
if (binary_length <= 208) {
|
|
|
809 |
this.target_bitsize = 208;
|
|
|
810 |
}
|
|
|
811 |
if (binary_length <= 160) {
|
|
|
812 |
this.target_bitsize = 160;
|
|
|
813 |
}
|
|
|
814 |
if (binary_length <= 104) {
|
|
|
815 |
this.target_bitsize = 104;
|
|
|
816 |
}
|
|
|
817 |
if (binary_length <= 56) {
|
|
|
818 |
this.target_bitsize = 56;
|
|
|
819 |
}
|
|
|
820 |
break;
|
|
|
821 |
case 3:
|
|
|
822 |
if (binary_length > 768) {
|
|
|
823 |
return false;
|
|
|
824 |
}
|
|
|
825 |
if (binary_length <= 768) {
|
|
|
826 |
this.target_bitsize = 768;
|
|
|
827 |
}
|
|
|
828 |
if (binary_length <= 648) {
|
|
|
829 |
this.target_bitsize = 648;
|
|
|
830 |
}
|
|
|
831 |
if (binary_length <= 536) {
|
|
|
832 |
this.target_bitsize = 536;
|
|
|
833 |
}
|
|
|
834 |
if (binary_length <= 416) {
|
|
|
835 |
this.target_bitsize = 416;
|
|
|
836 |
}
|
|
|
837 |
if (binary_length <= 304) {
|
|
|
838 |
this.target_bitsize = 304;
|
|
|
839 |
}
|
|
|
840 |
if (binary_length <= 208) {
|
|
|
841 |
this.target_bitsize = 208;
|
|
|
842 |
}
|
|
|
843 |
if (binary_length <= 152) {
|
|
|
844 |
this.target_bitsize = 152;
|
|
|
845 |
}
|
|
|
846 |
if (binary_length <= 112) {
|
|
|
847 |
this.target_bitsize = 112;
|
|
|
848 |
}
|
|
|
849 |
if (binary_length <= 72) {
|
|
|
850 |
this.target_bitsize = 72;
|
|
|
851 |
}
|
|
|
852 |
if (binary_length <= 32) {
|
|
|
853 |
this.target_bitsize = 32;
|
|
|
854 |
}
|
|
|
855 |
break;
|
|
|
856 |
case 4:
|
|
|
857 |
if (binary_length > 1184) {
|
|
|
858 |
return false;
|
|
|
859 |
}
|
|
|
860 |
if (binary_length <= 1184) {
|
|
|
861 |
this.target_bitsize = 1184;
|
|
|
862 |
}
|
|
|
863 |
if (binary_length <= 1016) {
|
|
|
864 |
this.target_bitsize = 1016;
|
|
|
865 |
}
|
|
|
866 |
if (binary_length <= 840) {
|
|
|
867 |
this.target_bitsize = 840;
|
|
|
868 |
}
|
|
|
869 |
if (binary_length <= 672) {
|
|
|
870 |
this.target_bitsize = 672;
|
|
|
871 |
}
|
|
|
872 |
if (binary_length <= 496) {
|
|
|
873 |
this.target_bitsize = 496;
|
|
|
874 |
}
|
|
|
875 |
if (binary_length <= 352) {
|
|
|
876 |
this.target_bitsize = 352;
|
|
|
877 |
}
|
|
|
878 |
if (binary_length <= 264) {
|
|
|
879 |
this.target_bitsize = 264;
|
|
|
880 |
}
|
|
|
881 |
if (binary_length <= 208) {
|
|
|
882 |
this.target_bitsize = 208;
|
|
|
883 |
}
|
|
|
884 |
if (binary_length <= 152) {
|
|
|
885 |
this.target_bitsize = 152;
|
|
|
886 |
}
|
|
|
887 |
if (binary_length <= 96) {
|
|
|
888 |
this.target_bitsize = 96;
|
|
|
889 |
}
|
|
|
890 |
if (binary_length <= 56) {
|
|
|
891 |
this.target_bitsize = 56;
|
|
|
892 |
}
|
|
|
893 |
break;
|
|
|
894 |
}
|
|
|
895 |
}
|
|
|
896 |
|
|
|
897 |
if (this.cc_mode == CompositeMode.CC_C) {
|
|
|
898 |
/* CC-C 2D Component is a bit more complex! */
|
|
|
899 |
int byte_length, codewords_used, ecc_level, ecc_codewords, rows;
|
|
|
900 |
int codewords_total, target_codewords, target_bytesize;
|
|
|
901 |
|
|
|
902 |
byte_length = binary_length / 8;
|
|
|
903 |
if (binary_length % 8 != 0) {
|
|
|
904 |
byte_length++;
|
|
|
905 |
}
|
|
|
906 |
|
|
|
907 |
codewords_used = byte_length / 6 * 5;
|
|
|
908 |
codewords_used += byte_length % 6;
|
|
|
909 |
|
|
|
910 |
ecc_level = 7;
|
|
|
911 |
if (codewords_used <= 1280) {
|
|
|
912 |
ecc_level = 6;
|
|
|
913 |
}
|
|
|
914 |
if (codewords_used <= 640) {
|
|
|
915 |
ecc_level = 5;
|
|
|
916 |
}
|
|
|
917 |
if (codewords_used <= 320) {
|
|
|
918 |
ecc_level = 4;
|
|
|
919 |
}
|
|
|
920 |
if (codewords_used <= 160) {
|
|
|
921 |
ecc_level = 3;
|
|
|
922 |
}
|
|
|
923 |
if (codewords_used <= 40) {
|
|
|
924 |
ecc_level = 2;
|
|
|
925 |
}
|
|
|
926 |
this.ecc = ecc_level;
|
|
|
927 |
ecc_codewords = 1;
|
|
|
928 |
for (i = 1; i <= ecc_level + 1; i++) {
|
|
|
929 |
ecc_codewords *= 2;
|
|
|
930 |
}
|
|
|
931 |
|
|
|
932 |
codewords_used += ecc_codewords;
|
|
|
933 |
codewords_used += 3;
|
|
|
934 |
|
|
|
935 |
if (this.linearWidth == 0) {
|
|
|
936 |
/* Linear component not yet calculated */
|
|
|
937 |
this.cc_width = (int) (0.5 + Math.sqrt(codewords_used / 3.0));
|
|
|
938 |
} else {
|
|
|
939 |
this.cc_width = (this.linearWidth - 53) / 17;
|
|
|
940 |
}
|
|
|
941 |
|
|
|
942 |
if (codewords_used / this.cc_width > 90) {
|
|
|
943 |
/* stop the symbol from becoming too high */
|
|
|
944 |
this.cc_width = this.cc_width + 1;
|
|
|
945 |
}
|
|
|
946 |
|
|
|
947 |
rows = codewords_used / this.cc_width;
|
|
|
948 |
if (codewords_used % this.cc_width != 0) {
|
|
|
949 |
rows++;
|
|
|
950 |
}
|
|
|
951 |
|
|
|
952 |
while (this.cc_width > 3 * rows) {
|
|
|
953 |
/* stop the symbol from becoming too wide (section 10) */
|
|
|
954 |
this.cc_width--;
|
|
|
955 |
|
|
|
956 |
rows = codewords_used / this.cc_width;
|
|
|
957 |
if (codewords_used % this.cc_width != 0) {
|
|
|
958 |
rows++;
|
|
|
959 |
}
|
|
|
960 |
}
|
|
|
961 |
|
|
|
962 |
codewords_total = this.cc_width * rows;
|
|
|
963 |
|
|
|
964 |
target_codewords = codewords_total - ecc_codewords;
|
|
|
965 |
target_codewords -= 3;
|
|
|
966 |
|
|
|
967 |
target_bytesize = 6 * (target_codewords / 5);
|
|
|
968 |
target_bytesize += target_codewords % 5;
|
|
|
969 |
|
|
|
970 |
this.target_bitsize = 8 * target_bytesize;
|
|
|
971 |
}
|
|
|
972 |
|
|
|
973 |
this.remainder = this.target_bitsize - binary_length;
|
|
|
974 |
return true;
|
|
|
975 |
}
|
|
|
976 |
|
|
|
977 |
private boolean cc_binary_string() {
|
|
|
978 |
/* Handles all data encodation from section 5 of ISO/IEC 24723 */
|
|
|
979 |
int encoding_method, read_posn, d1, d2, value, alpha_pad;
|
|
|
980 |
int i, j, ai_crop, fnc1_latch;
|
|
|
981 |
int group_val;
|
|
|
982 |
int ai90_mode;
|
|
|
983 |
boolean latch;
|
|
|
984 |
int alpha, alphanum, numeric, test1, test2, test3, next_ai_posn;
|
|
|
985 |
int numeric_value, table3_letter;
|
|
|
986 |
String numeric_part;
|
|
|
987 |
String ninety;
|
|
|
988 |
int latchOffset;
|
|
|
989 |
|
|
|
990 |
encoding_method = 1;
|
|
|
991 |
read_posn = 0;
|
|
|
992 |
ai_crop = 0;
|
|
|
993 |
fnc1_latch = 0;
|
|
|
994 |
alpha_pad = 0;
|
|
|
995 |
ai90_mode = 0;
|
|
|
996 |
this.ecc = 0;
|
|
|
997 |
value = 0;
|
|
|
998 |
this.target_bitsize = 0;
|
|
|
999 |
|
|
|
1000 |
if (this.content.charAt(0) == '1' && (this.content.charAt(1) == '0' || this.content.charAt(1) == '1' || this.content.charAt(1) == '7') && this.content.length() >= 8) {
|
|
|
1001 |
/* Source starts (10), (11) or (17) */
|
|
|
1002 |
encoding_method = 2;
|
|
|
1003 |
}
|
|
|
1004 |
|
|
|
1005 |
if (this.content.charAt(0) == '9' && this.content.charAt(1) == '0') {
|
|
|
1006 |
/* Source starts (90) */
|
|
|
1007 |
encoding_method = 3;
|
|
|
1008 |
}
|
|
|
1009 |
|
|
|
1010 |
info("Composite Encodation: ");
|
|
|
1011 |
switch (encoding_method) {
|
|
|
1012 |
case 1:
|
|
|
1013 |
infoLine("0");
|
|
|
1014 |
break;
|
|
|
1015 |
case 2:
|
|
|
1016 |
infoLine("10");
|
|
|
1017 |
break;
|
|
|
1018 |
case 3:
|
|
|
1019 |
infoLine("11");
|
|
|
1020 |
break;
|
|
|
1021 |
}
|
|
|
1022 |
|
|
|
1023 |
this.binary_string = "";
|
|
|
1024 |
|
|
|
1025 |
if (encoding_method == 1) {
|
|
|
1026 |
this.binary_string += "0";
|
|
|
1027 |
}
|
|
|
1028 |
|
|
|
1029 |
if (encoding_method == 2) {
|
|
|
1030 |
/* Encoding Method field "10" - date and lot number */
|
|
|
1031 |
|
|
|
1032 |
this.binary_string += "10";
|
|
|
1033 |
|
|
|
1034 |
if (this.content.charAt(1) == '0') {
|
|
|
1035 |
/* No date data */
|
|
|
1036 |
this.binary_string += "11";
|
|
|
1037 |
read_posn = 2;
|
|
|
1038 |
} else {
|
|
|
1039 |
/* Production Date (11) or Expiration Date (17) */
|
|
|
1040 |
group_val = (10 * (this.content.charAt(2) - '0') + this.content.charAt(3) - '0') * 384;
|
|
|
1041 |
group_val += (10 * (this.content.charAt(4) - '0') + this.content.charAt(5) - '0' - 1) * 32;
|
|
|
1042 |
group_val += 10 * (this.content.charAt(6) - '0') + this.content.charAt(7) - '0';
|
|
|
1043 |
|
|
|
1044 |
for (j = 0; j < 16; j++) {
|
|
|
1045 |
if ((group_val & 0x8000 >> j) == 0) {
|
|
|
1046 |
this.binary_string += "0";
|
|
|
1047 |
} else {
|
|
|
1048 |
this.binary_string += "1";
|
|
|
1049 |
}
|
|
|
1050 |
}
|
|
|
1051 |
|
|
|
1052 |
if (this.content.charAt(1) == '1') {
|
|
|
1053 |
/* Production Date AI 11 */
|
|
|
1054 |
this.binary_string += "0";
|
|
|
1055 |
} else {
|
|
|
1056 |
/* Expiration Date AI 17 */
|
|
|
1057 |
this.binary_string += "1";
|
|
|
1058 |
}
|
|
|
1059 |
read_posn = 8;
|
|
|
1060 |
}
|
|
|
1061 |
|
|
|
1062 |
if (read_posn + 2 < this.content.length()) {
|
|
|
1063 |
if (this.content.charAt(read_posn) == '1' && this.content.charAt(read_posn + 1) == '0') {
|
|
|
1064 |
/* Followed by AI 10 - strip this from general field */
|
|
|
1065 |
read_posn += 2;
|
|
|
1066 |
} else {
|
|
|
1067 |
/* An FNC1 character needs to be inserted in the general field */
|
|
|
1068 |
fnc1_latch = 1;
|
|
|
1069 |
}
|
|
|
1070 |
} else {
|
|
|
1071 |
fnc1_latch = 1;
|
|
|
1072 |
}
|
|
|
1073 |
}
|
|
|
1074 |
|
|
|
1075 |
if (encoding_method == 3) {
|
|
|
1076 |
/* Encodation Method field of "11" - AI 90 */
|
|
|
1077 |
/*
|
|
|
1078 |
* "This encodation method may be used if an element string with an AI 90 occurs at the
|
|
|
1079 |
* start of the data message, and if the data field following the two-digit AI 90 starts
|
|
|
1080 |
* with an alphanumeric string which complies with a specific format." (para 5.2.2)
|
|
|
1081 |
*/
|
|
|
1082 |
|
|
|
1083 |
j = this.content.length();
|
|
|
1084 |
for (i = this.content.length(); i > 2; i--) {
|
|
|
1085 |
if (this.content.charAt(i - 1) == '[') {
|
|
|
1086 |
j = i;
|
|
|
1087 |
}
|
|
|
1088 |
}
|
|
|
1089 |
|
|
|
1090 |
ninety = this.content.substring(2, j - 1);
|
|
|
1091 |
|
|
|
1092 |
/* Find out if the AI 90 data is alphabetic or numeric or both */
|
|
|
1093 |
|
|
|
1094 |
alpha = 0;
|
|
|
1095 |
alphanum = 0;
|
|
|
1096 |
numeric = 0;
|
|
|
1097 |
|
|
|
1098 |
for (i = 0; i < ninety.length(); i++) {
|
|
|
1099 |
|
|
|
1100 |
if (ninety.charAt(i) >= 'A' && ninety.charAt(i) <= 'Z') {
|
|
|
1101 |
/* Character is alphabetic */
|
|
|
1102 |
alpha += 1;
|
|
|
1103 |
}
|
|
|
1104 |
|
|
|
1105 |
if (ninety.charAt(i) >= '0' && ninety.charAt(i) <= '9') {
|
|
|
1106 |
/* Character is numeric */
|
|
|
1107 |
numeric += 1;
|
|
|
1108 |
}
|
|
|
1109 |
|
|
|
1110 |
switch (ninety.charAt(i)) {
|
|
|
1111 |
case '*':
|
|
|
1112 |
case ',':
|
|
|
1113 |
case '-':
|
|
|
1114 |
case '.':
|
|
|
1115 |
case '/':
|
|
|
1116 |
alphanum += 1;
|
|
|
1117 |
break;
|
|
|
1118 |
}
|
|
|
1119 |
|
|
|
1120 |
if (!(ninety.charAt(i) >= '0' && ninety.charAt(i) <= '9' || ninety.charAt(i) >= 'A' && ninety.charAt(i) <= 'Z')) {
|
|
|
1121 |
if (ninety.charAt(i) != '*' && ninety.charAt(i) != ',' && ninety.charAt(i) != '-' && ninety.charAt(i) != '.' && ninety.charAt(i) != '/') {
|
|
|
1122 |
/* An Invalid AI 90 character */
|
|
|
1123 |
throw new OkapiException("Invalid AI 90 data");
|
|
|
1124 |
}
|
|
|
1125 |
}
|
|
|
1126 |
}
|
|
|
1127 |
|
|
|
1128 |
/* must start with 0, 1, 2 or 3 digits followed by an uppercase character */
|
|
|
1129 |
test1 = -1;
|
|
|
1130 |
for (i = 3; i >= 0; i--) {
|
|
|
1131 |
if (ninety.charAt(i) >= 'A' && ninety.charAt(i) <= 'Z') {
|
|
|
1132 |
test1 = i;
|
|
|
1133 |
}
|
|
|
1134 |
}
|
|
|
1135 |
|
|
|
1136 |
test2 = 0;
|
|
|
1137 |
for (i = 0; i < test1; i++) {
|
|
|
1138 |
if (!(ninety.charAt(i) >= '0' && ninety.charAt(i) <= '9')) {
|
|
|
1139 |
test2 = 1;
|
|
|
1140 |
}
|
|
|
1141 |
}
|
|
|
1142 |
|
|
|
1143 |
/* leading zeros are not permitted */
|
|
|
1144 |
test3 = 0;
|
|
|
1145 |
if (test1 >= 1 && ninety.charAt(0) == '0') {
|
|
|
1146 |
test3 = 1;
|
|
|
1147 |
}
|
|
|
1148 |
|
|
|
1149 |
if (test1 != -1 && test2 != 1 && test3 == 0) {
|
|
|
1150 |
/* Encodation method "11" can be used */
|
|
|
1151 |
this.binary_string += "11";
|
|
|
1152 |
|
|
|
1153 |
numeric -= test1;
|
|
|
1154 |
alpha--;
|
|
|
1155 |
|
|
|
1156 |
/* Decide on numeric, alpha or alphanumeric mode */
|
|
|
1157 |
/* Alpha mode is a special mode for AI 90 */
|
|
|
1158 |
|
|
|
1159 |
if (alphanum > 0) {
|
|
|
1160 |
/* Alphanumeric mode */
|
|
|
1161 |
this.binary_string += "0";
|
|
|
1162 |
ai90_mode = 1;
|
|
|
1163 |
} else {
|
|
|
1164 |
if (alpha > numeric) {
|
|
|
1165 |
/* Alphabetic mode */
|
|
|
1166 |
this.binary_string += "11";
|
|
|
1167 |
ai90_mode = 2;
|
|
|
1168 |
} else {
|
|
|
1169 |
/* Numeric mode */
|
|
|
1170 |
this.binary_string += "10";
|
|
|
1171 |
ai90_mode = 3;
|
|
|
1172 |
}
|
|
|
1173 |
}
|
|
|
1174 |
|
|
|
1175 |
next_ai_posn = 2 + ninety.length();
|
|
|
1176 |
|
|
|
1177 |
if (this.content.charAt(next_ai_posn) == '[') {
|
|
|
1178 |
/* There are more AIs afterwords */
|
|
|
1179 |
if (this.content.charAt(next_ai_posn + 1) == '2' && this.content.charAt(next_ai_posn + 2) == '1') {
|
|
|
1180 |
/* AI 21 follows */
|
|
|
1181 |
ai_crop = 1;
|
|
|
1182 |
}
|
|
|
1183 |
|
|
|
1184 |
if (this.content.charAt(next_ai_posn + 1) == '8' && this.content.charAt(next_ai_posn + 2) == '0' && this.content.charAt(next_ai_posn + 3) == '0'
|
|
|
1185 |
&& this.content.charAt(next_ai_posn + 4) == '4') {
|
|
|
1186 |
/* AI 8004 follows */
|
|
|
1187 |
ai_crop = 2;
|
|
|
1188 |
}
|
|
|
1189 |
}
|
|
|
1190 |
|
|
|
1191 |
switch (ai_crop) {
|
|
|
1192 |
case 0:
|
|
|
1193 |
this.binary_string += "0";
|
|
|
1194 |
break;
|
|
|
1195 |
case 1:
|
|
|
1196 |
this.binary_string += "10";
|
|
|
1197 |
break;
|
|
|
1198 |
case 2:
|
|
|
1199 |
this.binary_string += "11";
|
|
|
1200 |
break;
|
|
|
1201 |
}
|
|
|
1202 |
|
|
|
1203 |
if (test1 == 0) {
|
|
|
1204 |
numeric_part = "0";
|
|
|
1205 |
} else {
|
|
|
1206 |
numeric_part = ninety.substring(0, test1);
|
|
|
1207 |
}
|
|
|
1208 |
|
|
|
1209 |
numeric_value = 0;
|
|
|
1210 |
for (i = 0; i < numeric_part.length(); i++) {
|
|
|
1211 |
numeric_value *= 10;
|
|
|
1212 |
numeric_value += numeric_part.charAt(i) - '0';
|
|
|
1213 |
}
|
|
|
1214 |
|
|
|
1215 |
table3_letter = -1;
|
|
|
1216 |
if (numeric_value < 31) {
|
|
|
1217 |
switch (ninety.charAt(test1)) {
|
|
|
1218 |
case 'B':
|
|
|
1219 |
table3_letter = 0;
|
|
|
1220 |
break;
|
|
|
1221 |
case 'D':
|
|
|
1222 |
table3_letter = 1;
|
|
|
1223 |
break;
|
|
|
1224 |
case 'H':
|
|
|
1225 |
table3_letter = 2;
|
|
|
1226 |
break;
|
|
|
1227 |
case 'I':
|
|
|
1228 |
table3_letter = 3;
|
|
|
1229 |
break;
|
|
|
1230 |
case 'J':
|
|
|
1231 |
table3_letter = 4;
|
|
|
1232 |
break;
|
|
|
1233 |
case 'K':
|
|
|
1234 |
table3_letter = 5;
|
|
|
1235 |
break;
|
|
|
1236 |
case 'L':
|
|
|
1237 |
table3_letter = 6;
|
|
|
1238 |
break;
|
|
|
1239 |
case 'N':
|
|
|
1240 |
table3_letter = 7;
|
|
|
1241 |
break;
|
|
|
1242 |
case 'P':
|
|
|
1243 |
table3_letter = 8;
|
|
|
1244 |
break;
|
|
|
1245 |
case 'Q':
|
|
|
1246 |
table3_letter = 9;
|
|
|
1247 |
break;
|
|
|
1248 |
case 'R':
|
|
|
1249 |
table3_letter = 10;
|
|
|
1250 |
break;
|
|
|
1251 |
case 'S':
|
|
|
1252 |
table3_letter = 11;
|
|
|
1253 |
break;
|
|
|
1254 |
case 'T':
|
|
|
1255 |
table3_letter = 12;
|
|
|
1256 |
break;
|
|
|
1257 |
case 'V':
|
|
|
1258 |
table3_letter = 13;
|
|
|
1259 |
break;
|
|
|
1260 |
case 'W':
|
|
|
1261 |
table3_letter = 14;
|
|
|
1262 |
break;
|
|
|
1263 |
case 'Z':
|
|
|
1264 |
table3_letter = 15;
|
|
|
1265 |
break;
|
|
|
1266 |
}
|
|
|
1267 |
}
|
|
|
1268 |
|
|
|
1269 |
if (table3_letter != -1) {
|
|
|
1270 |
/* Encoding can be done according to 5.2.2 c) 2) */
|
|
|
1271 |
/* five bit binary string representing value before letter */
|
|
|
1272 |
for (j = 0; j < 5; j++) {
|
|
|
1273 |
if ((numeric_value & 0x10 >> j) == 0x00) {
|
|
|
1274 |
this.binary_string += "0";
|
|
|
1275 |
} else {
|
|
|
1276 |
this.binary_string += "1";
|
|
|
1277 |
}
|
|
|
1278 |
}
|
|
|
1279 |
|
|
|
1280 |
/* followed by four bit representation of letter from Table 3 */
|
|
|
1281 |
for (j = 0; j < 4; j++) {
|
|
|
1282 |
if ((table3_letter & 0x08 >> j) == 0x00) {
|
|
|
1283 |
this.binary_string += "0";
|
|
|
1284 |
} else {
|
|
|
1285 |
this.binary_string += "1";
|
|
|
1286 |
}
|
|
|
1287 |
}
|
|
|
1288 |
} else {
|
|
|
1289 |
/* Encoding is done according to 5.2.2 c) 3) */
|
|
|
1290 |
this.binary_string += "11111";
|
|
|
1291 |
/* ten bit representation of number */
|
|
|
1292 |
for (j = 0; j < 10; j++) {
|
|
|
1293 |
if ((numeric_value & 0x200 >> j) == 0x00) {
|
|
|
1294 |
this.binary_string += "0";
|
|
|
1295 |
} else {
|
|
|
1296 |
this.binary_string += "1";
|
|
|
1297 |
}
|
|
|
1298 |
}
|
|
|
1299 |
|
|
|
1300 |
/* five bit representation of ASCII character */
|
|
|
1301 |
for (j = 0; j < 5; j++) {
|
|
|
1302 |
if ((ninety.charAt(test1) - 65 & 0x10 >> j) == 0x00) {
|
|
|
1303 |
this.binary_string += "0";
|
|
|
1304 |
} else {
|
|
|
1305 |
this.binary_string += "1";
|
|
|
1306 |
}
|
|
|
1307 |
}
|
|
|
1308 |
}
|
|
|
1309 |
|
|
|
1310 |
read_posn = test1 + 3;
|
|
|
1311 |
} else {
|
|
|
1312 |
/* Use general field encodation instead */
|
|
|
1313 |
this.binary_string += "0";
|
|
|
1314 |
read_posn = 0;
|
|
|
1315 |
}
|
|
|
1316 |
|
|
|
1317 |
/* Now encode the rest of the AI 90 data field */
|
|
|
1318 |
if (ai90_mode == 2) {
|
|
|
1319 |
/* Alpha encodation (section 5.2.3) */
|
|
|
1320 |
do {
|
|
|
1321 |
if (this.content.charAt(read_posn) >= '0' && this.content.charAt(read_posn) <= '9') {
|
|
|
1322 |
for (j = 0; j < 5; j++) {
|
|
|
1323 |
if ((this.content.charAt(read_posn) + 4 & 0x10 >> j) == 0x00) {
|
|
|
1324 |
this.binary_string += "0";
|
|
|
1325 |
} else {
|
|
|
1326 |
this.binary_string += "1";
|
|
|
1327 |
}
|
|
|
1328 |
}
|
|
|
1329 |
}
|
|
|
1330 |
|
|
|
1331 |
if (this.content.charAt(read_posn) >= 'A' && this.content.charAt(read_posn) <= 'Z') {
|
|
|
1332 |
for (j = 0; j < 6; j++) {
|
|
|
1333 |
if ((this.content.charAt(read_posn) - 65 & 0x20 >> j) == 0x00) {
|
|
|
1334 |
this.binary_string += "0";
|
|
|
1335 |
} else {
|
|
|
1336 |
this.binary_string += "1";
|
|
|
1337 |
}
|
|
|
1338 |
}
|
|
|
1339 |
}
|
|
|
1340 |
|
|
|
1341 |
if (this.content.charAt(read_posn) == '[') {
|
|
|
1342 |
this.binary_string += "11111";
|
|
|
1343 |
}
|
|
|
1344 |
|
|
|
1345 |
read_posn++;
|
|
|
1346 |
} while (this.content.charAt(read_posn - 1) != '[' && read_posn < this.content.length());
|
|
|
1347 |
alpha_pad = 1; /* This is overwritten if a general field is encoded */
|
|
|
1348 |
}
|
|
|
1349 |
|
|
|
1350 |
if (ai90_mode == 1) {
|
|
|
1351 |
/* Alphanumeric mode */
|
|
|
1352 |
do {
|
|
|
1353 |
if (this.content.charAt(read_posn) >= '0' && this.content.charAt(read_posn) <= '9') {
|
|
|
1354 |
for (j = 0; j < 5; j++) {
|
|
|
1355 |
if ((this.content.charAt(read_posn) - 43 & 0x10 >> j) == 0x00) {
|
|
|
1356 |
this.binary_string += "0";
|
|
|
1357 |
} else {
|
|
|
1358 |
this.binary_string += "1";
|
|
|
1359 |
}
|
|
|
1360 |
}
|
|
|
1361 |
}
|
|
|
1362 |
|
|
|
1363 |
if (this.content.charAt(read_posn) >= 'A' && this.content.charAt(read_posn) <= 'Z') {
|
|
|
1364 |
for (j = 0; j < 6; j++) {
|
|
|
1365 |
if ((this.content.charAt(read_posn) - 33 & 0x20 >> j) == 0x00) {
|
|
|
1366 |
this.binary_string += "0";
|
|
|
1367 |
} else {
|
|
|
1368 |
this.binary_string += "1";
|
|
|
1369 |
}
|
|
|
1370 |
}
|
|
|
1371 |
}
|
|
|
1372 |
|
|
|
1373 |
switch (this.content.charAt(read_posn)) {
|
|
|
1374 |
case '[':
|
|
|
1375 |
this.binary_string += "01111";
|
|
|
1376 |
break;
|
|
|
1377 |
case '*':
|
|
|
1378 |
this.binary_string += "111010";
|
|
|
1379 |
break;
|
|
|
1380 |
case ',':
|
|
|
1381 |
this.binary_string += "111011";
|
|
|
1382 |
break;
|
|
|
1383 |
case '-':
|
|
|
1384 |
this.binary_string += "111100";
|
|
|
1385 |
break;
|
|
|
1386 |
case '.':
|
|
|
1387 |
this.binary_string += "111101";
|
|
|
1388 |
break;
|
|
|
1389 |
case '/':
|
|
|
1390 |
this.binary_string += "111110";
|
|
|
1391 |
break;
|
|
|
1392 |
}
|
|
|
1393 |
|
|
|
1394 |
read_posn++;
|
|
|
1395 |
} while (this.content.charAt(read_posn - 1) != '[' && this.content.charAt(read_posn - 1) != '\0');
|
|
|
1396 |
}
|
|
|
1397 |
|
|
|
1398 |
read_posn += 2 * ai_crop;
|
|
|
1399 |
}
|
|
|
1400 |
|
|
|
1401 |
/*
|
|
|
1402 |
* The compressed data field has been processed if appropriate - the rest of the data (if
|
|
|
1403 |
* any) goes into a general-purpose data compaction field
|
|
|
1404 |
*/
|
|
|
1405 |
|
|
|
1406 |
j = 0;
|
|
|
1407 |
this.general_field = "";
|
|
|
1408 |
if (fnc1_latch == 1) {
|
|
|
1409 |
/*
|
|
|
1410 |
* Encodation method "10" has been used but it is not followed by AI 10, so a FNC1
|
|
|
1411 |
* character needs to be added
|
|
|
1412 |
*/
|
|
|
1413 |
this.general_field += "[";
|
|
|
1414 |
}
|
|
|
1415 |
|
|
|
1416 |
this.general_field += this.content.substring(read_posn);
|
|
|
1417 |
|
|
|
1418 |
latch = false;
|
|
|
1419 |
if (this.general_field.length() != 0) {
|
|
|
1420 |
alpha_pad = 0;
|
|
|
1421 |
|
|
|
1422 |
this.general_field_type = new GeneralFieldMode[this.general_field.length()];
|
|
|
1423 |
|
|
|
1424 |
for (i = 0; i < this.general_field.length(); i++) {
|
|
|
1425 |
/* Table 13 - ISO/IEC 646 encodation */
|
|
|
1426 |
if (this.general_field.charAt(i) < ' ' || this.general_field.charAt(i) > 'z') {
|
|
|
1427 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1428 |
latch = true;
|
|
|
1429 |
} else {
|
|
|
1430 |
this.general_field_type[i] = GeneralFieldMode.ISOIEC;
|
|
|
1431 |
}
|
|
|
1432 |
|
|
|
1433 |
if (this.general_field.charAt(i) == '#') {
|
|
|
1434 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1435 |
latch = true;
|
|
|
1436 |
}
|
|
|
1437 |
if (this.general_field.charAt(i) == '$') {
|
|
|
1438 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1439 |
latch = true;
|
|
|
1440 |
}
|
|
|
1441 |
if (this.general_field.charAt(i) == '@') {
|
|
|
1442 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1443 |
latch = true;
|
|
|
1444 |
}
|
|
|
1445 |
if (this.general_field.charAt(i) == 92) {
|
|
|
1446 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1447 |
latch = true;
|
|
|
1448 |
}
|
|
|
1449 |
if (this.general_field.charAt(i) == '^') {
|
|
|
1450 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1451 |
latch = true;
|
|
|
1452 |
}
|
|
|
1453 |
if (this.general_field.charAt(i) == 96) {
|
|
|
1454 |
this.general_field_type[i] = GeneralFieldMode.INVALID_CHAR;
|
|
|
1455 |
latch = true;
|
|
|
1456 |
}
|
|
|
1457 |
|
|
|
1458 |
/* Table 12 - Alphanumeric encodation */
|
|
|
1459 |
if (this.general_field.charAt(i) >= 'A' && this.general_field.charAt(i) <= 'Z') {
|
|
|
1460 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1461 |
}
|
|
|
1462 |
if (this.general_field.charAt(i) == '*') {
|
|
|
1463 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1464 |
}
|
|
|
1465 |
if (this.general_field.charAt(i) == ',') {
|
|
|
1466 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1467 |
}
|
|
|
1468 |
if (this.general_field.charAt(i) == '-') {
|
|
|
1469 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1470 |
}
|
|
|
1471 |
if (this.general_field.charAt(i) == '.') {
|
|
|
1472 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1473 |
}
|
|
|
1474 |
if (this.general_field.charAt(i) == '/') {
|
|
|
1475 |
this.general_field_type[i] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1476 |
}
|
|
|
1477 |
|
|
|
1478 |
/* Numeric encodation */
|
|
|
1479 |
if (this.general_field.charAt(i) >= '0' && this.general_field.charAt(i) <= '9') {
|
|
|
1480 |
this.general_field_type[i] = GeneralFieldMode.ANY_ENC;
|
|
|
1481 |
}
|
|
|
1482 |
if (this.general_field.charAt(i) == '[') {
|
|
|
1483 |
/* FNC1 can be encoded in any system */
|
|
|
1484 |
this.general_field_type[i] = GeneralFieldMode.ANY_ENC;
|
|
|
1485 |
}
|
|
|
1486 |
|
|
|
1487 |
}
|
|
|
1488 |
|
|
|
1489 |
if (latch) {
|
|
|
1490 |
/* Invalid characters in input data */
|
|
|
1491 |
throw new OkapiException("Invalid characters in input data");
|
|
|
1492 |
}
|
|
|
1493 |
|
|
|
1494 |
for (i = 0; i < this.general_field.length() - 1; i++) {
|
|
|
1495 |
if (this.general_field_type[i] == GeneralFieldMode.ISOIEC && this.general_field.charAt(i + 1) == '[') {
|
|
|
1496 |
this.general_field_type[i + 1] = GeneralFieldMode.ISOIEC;
|
|
|
1497 |
}
|
|
|
1498 |
}
|
|
|
1499 |
|
|
|
1500 |
for (i = 0; i < this.general_field.length() - 1; i++) {
|
|
|
1501 |
if (this.general_field_type[i] == GeneralFieldMode.ALPHA_OR_ISO && this.general_field.charAt(i + 1) == '[') {
|
|
|
1502 |
this.general_field_type[i + 1] = GeneralFieldMode.ALPHA_OR_ISO;
|
|
|
1503 |
}
|
|
|
1504 |
}
|
|
|
1505 |
|
|
|
1506 |
latch = applyGeneralFieldRules();
|
|
|
1507 |
|
|
|
1508 |
i = 0;
|
|
|
1509 |
do {
|
|
|
1510 |
switch (this.general_field_type[i]) {
|
|
|
1511 |
case NUMERIC:
|
|
|
1512 |
if (i != 0) {
|
|
|
1513 |
if (this.general_field_type[i - 1] != GeneralFieldMode.NUMERIC && this.general_field.charAt(i - 1) != '[') {
|
|
|
1514 |
this.binary_string += "000"; /* Numeric latch */
|
|
|
1515 |
}
|
|
|
1516 |
}
|
|
|
1517 |
|
|
|
1518 |
if (this.general_field.charAt(i) != '[') {
|
|
|
1519 |
d1 = this.general_field.charAt(i) - '0';
|
|
|
1520 |
} else {
|
|
|
1521 |
d1 = 10;
|
|
|
1522 |
}
|
|
|
1523 |
|
|
|
1524 |
if (i < this.general_field.length() - 1) {
|
|
|
1525 |
if (this.general_field.charAt(i + 1) != '[') {
|
|
|
1526 |
d2 = this.general_field.charAt(i + 1) - '0';
|
|
|
1527 |
} else {
|
|
|
1528 |
d2 = 10;
|
|
|
1529 |
}
|
|
|
1530 |
} else {
|
|
|
1531 |
d2 = 10;
|
|
|
1532 |
}
|
|
|
1533 |
|
|
|
1534 |
if (d1 != 10 || d2 != 10) {
|
|
|
1535 |
/* If (d1==10)&&(d2==10) then input is either FNC1,FNC1 or FNC1,EOL */
|
|
|
1536 |
value = 11 * d1 + d2 + 8;
|
|
|
1537 |
|
|
|
1538 |
for (j = 0; j < 7; j++) {
|
|
|
1539 |
if ((value & 0x40 >> j) == 0x00) {
|
|
|
1540 |
this.binary_string += "0";
|
|
|
1541 |
} else {
|
|
|
1542 |
this.binary_string += "1";
|
|
|
1543 |
}
|
|
|
1544 |
}
|
|
|
1545 |
|
|
|
1546 |
i += 2;
|
|
|
1547 |
}
|
|
|
1548 |
break;
|
|
|
1549 |
|
|
|
1550 |
case ALPHA:
|
|
|
1551 |
if (i != 0) {
|
|
|
1552 |
if (this.general_field_type[i - 1] == GeneralFieldMode.NUMERIC || this.general_field.charAt(i - 1) == '[') {
|
|
|
1553 |
this.binary_string += "0000"; /* Alphanumeric latch */
|
|
|
1554 |
}
|
|
|
1555 |
if (this.general_field_type[i - 1] == GeneralFieldMode.ISOIEC) {
|
|
|
1556 |
this.binary_string += "00100"; /* ISO/IEC 646 latch */
|
|
|
1557 |
}
|
|
|
1558 |
}
|
|
|
1559 |
|
|
|
1560 |
if (this.general_field.charAt(i) >= '0' && this.general_field.charAt(i) <= '9') {
|
|
|
1561 |
|
|
|
1562 |
value = this.general_field.charAt(i) - 43;
|
|
|
1563 |
|
|
|
1564 |
for (j = 0; j < 5; j++) {
|
|
|
1565 |
if ((value & 0x10 >> j) == 0x00) {
|
|
|
1566 |
this.binary_string += "0";
|
|
|
1567 |
} else {
|
|
|
1568 |
this.binary_string += "1";
|
|
|
1569 |
}
|
|
|
1570 |
}
|
|
|
1571 |
}
|
|
|
1572 |
|
|
|
1573 |
if (this.general_field.charAt(i) >= 'A' && this.general_field.charAt(i) <= 'Z') {
|
|
|
1574 |
|
|
|
1575 |
value = this.general_field.charAt(i) - 33;
|
|
|
1576 |
|
|
|
1577 |
for (j = 0; j < 6; j++) {
|
|
|
1578 |
if ((value & 0x20 >> j) == 0x00) {
|
|
|
1579 |
this.binary_string += "0";
|
|
|
1580 |
} else {
|
|
|
1581 |
this.binary_string += "1";
|
|
|
1582 |
}
|
|
|
1583 |
}
|
|
|
1584 |
}
|
|
|
1585 |
|
|
|
1586 |
if (this.general_field.charAt(i) == '[') {
|
|
|
1587 |
this.binary_string += "01111"; /* FNC1/Numeric latch */
|
|
|
1588 |
}
|
|
|
1589 |
if (this.general_field.charAt(i) == '*') {
|
|
|
1590 |
this.binary_string += "111010"; /* asterisk */
|
|
|
1591 |
}
|
|
|
1592 |
if (this.general_field.charAt(i) == ',') {
|
|
|
1593 |
this.binary_string += "111011"; /* comma */
|
|
|
1594 |
}
|
|
|
1595 |
if (this.general_field.charAt(i) == '-') {
|
|
|
1596 |
this.binary_string += "111100"; /* minus or hyphen */
|
|
|
1597 |
}
|
|
|
1598 |
if (this.general_field.charAt(i) == '.') {
|
|
|
1599 |
this.binary_string += "111101"; /* period or full stop */
|
|
|
1600 |
}
|
|
|
1601 |
if (this.general_field.charAt(i) == '/') {
|
|
|
1602 |
this.binary_string += "111110"; /* slash or solidus */
|
|
|
1603 |
}
|
|
|
1604 |
|
|
|
1605 |
i++;
|
|
|
1606 |
break;
|
|
|
1607 |
|
|
|
1608 |
case ISOIEC:
|
|
|
1609 |
if (i != 0) {
|
|
|
1610 |
if (this.general_field_type[i - 1] == GeneralFieldMode.NUMERIC || this.general_field.charAt(i - 1) == '[') {
|
|
|
1611 |
this.binary_string += "0000"; /* Alphanumeric latch */
|
|
|
1612 |
this.binary_string += "00100"; /* ISO/IEC 646 latch */
|
|
|
1613 |
}
|
|
|
1614 |
if (this.general_field_type[i - 1] == GeneralFieldMode.ALPHA) {
|
|
|
1615 |
this.binary_string += "00100"; /* ISO/IEC 646 latch */
|
|
|
1616 |
}
|
|
|
1617 |
}
|
|
|
1618 |
|
|
|
1619 |
if (this.general_field.charAt(i) >= '0' && this.general_field.charAt(i) <= '9') {
|
|
|
1620 |
|
|
|
1621 |
value = this.general_field.charAt(i) - 43;
|
|
|
1622 |
|
|
|
1623 |
for (j = 0; j < 5; j++) {
|
|
|
1624 |
if ((value & 0x10 >> j) == 0x00) {
|
|
|
1625 |
this.binary_string += "0";
|
|
|
1626 |
} else {
|
|
|
1627 |
this.binary_string += "1";
|
|
|
1628 |
}
|
|
|
1629 |
}
|
|
|
1630 |
}
|
|
|
1631 |
|
|
|
1632 |
if (this.general_field.charAt(i) >= 'A' && this.general_field.charAt(i) <= 'Z') {
|
|
|
1633 |
|
|
|
1634 |
value = this.general_field.charAt(i) - 1;
|
|
|
1635 |
|
|
|
1636 |
for (j = 0; j < 7; j++) {
|
|
|
1637 |
if ((value & 0x40 >> j) == 0x00) {
|
|
|
1638 |
this.binary_string += "0";
|
|
|
1639 |
} else {
|
|
|
1640 |
this.binary_string += "1";
|
|
|
1641 |
}
|
|
|
1642 |
}
|
|
|
1643 |
}
|
|
|
1644 |
|
|
|
1645 |
if (this.general_field.charAt(i) >= 'a' && this.general_field.charAt(i) <= 'z') {
|
|
|
1646 |
|
|
|
1647 |
value = this.general_field.charAt(i) - 7;
|
|
|
1648 |
|
|
|
1649 |
for (j = 0; j < 7; j++) {
|
|
|
1650 |
if ((value & 0x40 >> j) == 0x00) {
|
|
|
1651 |
this.binary_string += "0";
|
|
|
1652 |
} else {
|
|
|
1653 |
this.binary_string += "1";
|
|
|
1654 |
}
|
|
|
1655 |
}
|
|
|
1656 |
}
|
|
|
1657 |
|
|
|
1658 |
if (this.general_field.charAt(i) == '[') {
|
|
|
1659 |
this.binary_string += "01111"; /* FNC1/Numeric latch */
|
|
|
1660 |
}
|
|
|
1661 |
if (this.general_field.charAt(i) == '!') {
|
|
|
1662 |
this.binary_string += "11101000"; /* exclamation mark */
|
|
|
1663 |
}
|
|
|
1664 |
if (this.general_field.charAt(i) == 34) {
|
|
|
1665 |
this.binary_string += "11101001"; /* quotation mark */
|
|
|
1666 |
}
|
|
|
1667 |
if (this.general_field.charAt(i) == 37) {
|
|
|
1668 |
this.binary_string += "11101010"; /* percent sign */
|
|
|
1669 |
}
|
|
|
1670 |
if (this.general_field.charAt(i) == '&') {
|
|
|
1671 |
this.binary_string += "11101011"; /* ampersand */
|
|
|
1672 |
}
|
|
|
1673 |
if (this.general_field.charAt(i) == 39) {
|
|
|
1674 |
this.binary_string += "11101100"; /* apostrophe */
|
|
|
1675 |
}
|
|
|
1676 |
if (this.general_field.charAt(i) == '(') {
|
|
|
1677 |
this.binary_string += "11101101"; /* left parenthesis */
|
|
|
1678 |
}
|
|
|
1679 |
if (this.general_field.charAt(i) == ')') {
|
|
|
1680 |
this.binary_string += "11101110"; /* right parenthesis */
|
|
|
1681 |
}
|
|
|
1682 |
if (this.general_field.charAt(i) == '*') {
|
|
|
1683 |
this.binary_string += "11101111"; /* asterisk */
|
|
|
1684 |
}
|
|
|
1685 |
if (this.general_field.charAt(i) == '+') {
|
|
|
1686 |
this.binary_string += "11110000"; /* plus sign */
|
|
|
1687 |
}
|
|
|
1688 |
if (this.general_field.charAt(i) == ',') {
|
|
|
1689 |
this.binary_string += "11110001"; /* comma */
|
|
|
1690 |
}
|
|
|
1691 |
if (this.general_field.charAt(i) == '-') {
|
|
|
1692 |
this.binary_string += "11110010"; /* minus or hyphen */
|
|
|
1693 |
}
|
|
|
1694 |
if (this.general_field.charAt(i) == '.') {
|
|
|
1695 |
this.binary_string += "11110011"; /* period or full stop */
|
|
|
1696 |
}
|
|
|
1697 |
if (this.general_field.charAt(i) == '/') {
|
|
|
1698 |
this.binary_string += "11110100"; /* slash or solidus */
|
|
|
1699 |
}
|
|
|
1700 |
if (this.general_field.charAt(i) == ':') {
|
|
|
1701 |
this.binary_string += "11110101"; /* colon */
|
|
|
1702 |
}
|
|
|
1703 |
if (this.general_field.charAt(i) == ';') {
|
|
|
1704 |
this.binary_string += "11110110"; /* semicolon */
|
|
|
1705 |
}
|
|
|
1706 |
if (this.general_field.charAt(i) == '<') {
|
|
|
1707 |
this.binary_string += "11110111"; /* less-than sign */
|
|
|
1708 |
}
|
|
|
1709 |
if (this.general_field.charAt(i) == '=') {
|
|
|
1710 |
this.binary_string += "11111000"; /* equals sign */
|
|
|
1711 |
}
|
|
|
1712 |
if (this.general_field.charAt(i) == '>') {
|
|
|
1713 |
this.binary_string += "11111001"; /* greater-than sign */
|
|
|
1714 |
}
|
|
|
1715 |
if (this.general_field.charAt(i) == '?') {
|
|
|
1716 |
this.binary_string += "11111010"; /* question mark */
|
|
|
1717 |
}
|
|
|
1718 |
if (this.general_field.charAt(i) == '_') {
|
|
|
1719 |
this.binary_string += "11111011"; /* underline or low line */
|
|
|
1720 |
}
|
|
|
1721 |
if (this.general_field.charAt(i) == ' ') {
|
|
|
1722 |
this.binary_string += "11111100"; /* space */
|
|
|
1723 |
}
|
|
|
1724 |
|
|
|
1725 |
i++;
|
|
|
1726 |
break;
|
|
|
1727 |
}
|
|
|
1728 |
|
|
|
1729 |
latchOffset = 0;
|
|
|
1730 |
if (latch) {
|
|
|
1731 |
latchOffset = 1;
|
|
|
1732 |
}
|
|
|
1733 |
} while (i + latchOffset < this.general_field.length());
|
|
|
1734 |
}
|
|
|
1735 |
|
|
|
1736 |
if (!calculateSymbolSize()) {
|
|
|
1737 |
return false;
|
|
|
1738 |
}
|
|
|
1739 |
|
|
|
1740 |
if (latch) {
|
|
|
1741 |
i = this.general_field.length() - 1;
|
|
|
1742 |
/* There is still one more numeric digit to encode */
|
|
|
1743 |
|
|
|
1744 |
if (this.general_field.charAt(i) == '[') {
|
|
|
1745 |
this.binary_string += "000001111";
|
|
|
1746 |
} else {
|
|
|
1747 |
if (this.remainder >= 4 && this.remainder <= 6) {
|
|
|
1748 |
d1 = this.general_field.charAt(i) - '0';
|
|
|
1749 |
d1++;
|
|
|
1750 |
|
|
|
1751 |
for (j = 0; j < 4; j++) {
|
|
|
1752 |
if ((value & 0x08 >> j) == 0x00) {
|
|
|
1753 |
this.binary_string += "0";
|
|
|
1754 |
} else {
|
|
|
1755 |
this.binary_string += "1";
|
|
|
1756 |
}
|
|
|
1757 |
}
|
|
|
1758 |
} else {
|
|
|
1759 |
d1 = this.general_field.charAt(i) - '0';
|
|
|
1760 |
d2 = 10;
|
|
|
1761 |
|
|
|
1762 |
value = 11 * d1 + d2 + 8;
|
|
|
1763 |
|
|
|
1764 |
for (j = 0; j < 7; j++) {
|
|
|
1765 |
if ((value & 0x40 >> j) == 0x00) {
|
|
|
1766 |
this.binary_string += "0";
|
|
|
1767 |
} else {
|
|
|
1768 |
this.binary_string += "1";
|
|
|
1769 |
}
|
|
|
1770 |
}
|
|
|
1771 |
/* This may push the symbol up to the next size */
|
|
|
1772 |
}
|
|
|
1773 |
}
|
|
|
1774 |
}
|
|
|
1775 |
|
|
|
1776 |
if (this.binary_string.length() > 11805) { /* (2361 * 5) */
|
|
|
1777 |
throw new OkapiException("Input too long");
|
|
|
1778 |
}
|
|
|
1779 |
|
|
|
1780 |
/* size of the symbol may have changed when adding data in the above sequence */
|
|
|
1781 |
if (!calculateSymbolSize()) {
|
|
|
1782 |
return false;
|
|
|
1783 |
}
|
|
|
1784 |
|
|
|
1785 |
infoLine("Composite Binary Length: " + this.binary_string.length());
|
|
|
1786 |
displayBinaryString();
|
|
|
1787 |
|
|
|
1788 |
if (this.binary_string.length() < this.target_bitsize) {
|
|
|
1789 |
/* Now add padding to binary string */
|
|
|
1790 |
if (alpha_pad == 1) {
|
|
|
1791 |
this.binary_string += "11111";
|
|
|
1792 |
alpha_pad = 0;
|
|
|
1793 |
/* Extra FNC1 character required after Alpha encodation (section 5.2.3) */
|
|
|
1794 |
}
|
|
|
1795 |
|
|
|
1796 |
if (this.general_field.length() != 0 && this.general_field_type[this.general_field.length() - 1] == GeneralFieldMode.NUMERIC) {
|
|
|
1797 |
this.binary_string += "0000";
|
|
|
1798 |
}
|
|
|
1799 |
|
|
|
1800 |
while (this.binary_string.length() < this.target_bitsize) {
|
|
|
1801 |
this.binary_string += "00100";
|
|
|
1802 |
}
|
|
|
1803 |
|
|
|
1804 |
this.binary_string = this.binary_string.substring(0, this.target_bitsize);
|
|
|
1805 |
}
|
|
|
1806 |
|
|
|
1807 |
return true;
|
|
|
1808 |
}
|
|
|
1809 |
|
|
|
1810 |
private void displayBinaryString() {
|
|
|
1811 |
int i, nibble;
|
|
|
1812 |
/* Display binary string as hexadecimal */
|
|
|
1813 |
|
|
|
1814 |
info("Composite Binary String: ");
|
|
|
1815 |
nibble = 0;
|
|
|
1816 |
for (i = 0; i < this.binary_string.length(); i++) {
|
|
|
1817 |
switch (i % 4) {
|
|
|
1818 |
case 0:
|
|
|
1819 |
if (this.binary_string.charAt(i) == '1') {
|
|
|
1820 |
nibble += 8;
|
|
|
1821 |
}
|
|
|
1822 |
break;
|
|
|
1823 |
case 1:
|
|
|
1824 |
if (this.binary_string.charAt(i) == '1') {
|
|
|
1825 |
nibble += 4;
|
|
|
1826 |
}
|
|
|
1827 |
break;
|
|
|
1828 |
case 2:
|
|
|
1829 |
if (this.binary_string.charAt(i) == '1') {
|
|
|
1830 |
nibble += 2;
|
|
|
1831 |
}
|
|
|
1832 |
break;
|
|
|
1833 |
case 3:
|
|
|
1834 |
if (this.binary_string.charAt(i) == '1') {
|
|
|
1835 |
nibble += 1;
|
|
|
1836 |
}
|
|
|
1837 |
info(Integer.toHexString(nibble));
|
|
|
1838 |
nibble = 0;
|
|
|
1839 |
break;
|
|
|
1840 |
}
|
|
|
1841 |
}
|
|
|
1842 |
|
|
|
1843 |
if (this.binary_string.length() % 4 != 0) {
|
|
|
1844 |
info(Integer.toHexString(nibble));
|
|
|
1845 |
}
|
|
|
1846 |
infoLine();
|
|
|
1847 |
}
|
|
|
1848 |
|
|
|
1849 |
private boolean applyGeneralFieldRules() {
|
|
|
1850 |
/*
|
|
|
1851 |
* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3 of ISO/IEC
|
|
|
1852 |
* 24724:2006
|
|
|
1853 |
*/
|
|
|
1854 |
|
|
|
1855 |
int block_count, i, j, k;
|
|
|
1856 |
GeneralFieldMode current, next, last;
|
|
|
1857 |
final int[] blockLength = new int[200];
|
|
|
1858 |
final GeneralFieldMode[] blockType = new GeneralFieldMode[200];
|
|
|
1859 |
|
|
|
1860 |
block_count = 0;
|
|
|
1861 |
|
|
|
1862 |
blockLength[block_count] = 1;
|
|
|
1863 |
blockType[block_count] = this.general_field_type[0];
|
|
|
1864 |
|
|
|
1865 |
for (i = 1; i < this.general_field.length(); i++) {
|
|
|
1866 |
current = this.general_field_type[i];
|
|
|
1867 |
last = this.general_field_type[i - 1];
|
|
|
1868 |
|
|
|
1869 |
if (current == last) {
|
|
|
1870 |
blockLength[block_count] = blockLength[block_count] + 1;
|
|
|
1871 |
} else {
|
|
|
1872 |
block_count++;
|
|
|
1873 |
blockLength[block_count] = 1;
|
|
|
1874 |
blockType[block_count] = this.general_field_type[i];
|
|
|
1875 |
}
|
|
|
1876 |
}
|
|
|
1877 |
|
|
|
1878 |
block_count++;
|
|
|
1879 |
|
|
|
1880 |
for (i = 0; i < block_count; i++) {
|
|
|
1881 |
current = blockType[i];
|
|
|
1882 |
next = blockType[i + 1];
|
|
|
1883 |
|
|
|
1884 |
if (current == GeneralFieldMode.ISOIEC && i != block_count - 1) {
|
|
|
1885 |
if (next == GeneralFieldMode.ANY_ENC && blockLength[i + 1] >= 4) {
|
|
|
1886 |
blockType[i + 1] = GeneralFieldMode.NUMERIC;
|
|
|
1887 |
}
|
|
|
1888 |
if (next == GeneralFieldMode.ANY_ENC && blockLength[i + 1] < 4) {
|
|
|
1889 |
blockType[i + 1] = GeneralFieldMode.ISOIEC;
|
|
|
1890 |
}
|
|
|
1891 |
if (next == GeneralFieldMode.ALPHA_OR_ISO && blockLength[i + 1] >= 5) {
|
|
|
1892 |
blockType[i + 1] = GeneralFieldMode.ALPHA;
|
|
|
1893 |
}
|
|
|
1894 |
if (next == GeneralFieldMode.ALPHA_OR_ISO && blockLength[i + 1] < 5) {
|
|
|
1895 |
blockType[i + 1] = GeneralFieldMode.ISOIEC;
|
|
|
1896 |
}
|
|
|
1897 |
}
|
|
|
1898 |
|
|
|
1899 |
if (current == GeneralFieldMode.ALPHA_OR_ISO) {
|
|
|
1900 |
blockType[i] = GeneralFieldMode.ALPHA;
|
|
|
1901 |
}
|
|
|
1902 |
|
|
|
1903 |
if (current == GeneralFieldMode.ALPHA && i != block_count - 1) {
|
|
|
1904 |
if (next == GeneralFieldMode.ANY_ENC && blockLength[i + 1] >= 6) {
|
|
|
1905 |
blockType[i + 1] = GeneralFieldMode.NUMERIC;
|
|
|
1906 |
}
|
|
|
1907 |
if (next == GeneralFieldMode.ANY_ENC && blockLength[i + 1] < 6) {
|
|
|
1908 |
if (i == block_count - 2 && blockLength[i + 1] >= 4) {
|
|
|
1909 |
blockType[i + 1] = GeneralFieldMode.NUMERIC;
|
|
|
1910 |
} else {
|
|
|
1911 |
blockType[i + 1] = GeneralFieldMode.ALPHA;
|
|
|
1912 |
}
|
|
|
1913 |
}
|
|
|
1914 |
}
|
|
|
1915 |
|
|
|
1916 |
if (current == GeneralFieldMode.ANY_ENC) {
|
|
|
1917 |
blockType[i] = GeneralFieldMode.NUMERIC;
|
|
|
1918 |
}
|
|
|
1919 |
}
|
|
|
1920 |
|
|
|
1921 |
if (block_count > 1) {
|
|
|
1922 |
i = 1;
|
|
|
1923 |
while (i < block_count) {
|
|
|
1924 |
if (blockType[i - 1] == blockType[i]) {
|
|
|
1925 |
/* bring together */
|
|
|
1926 |
blockLength[i - 1] = blockLength[i - 1] + blockLength[i];
|
|
|
1927 |
j = i + 1;
|
|
|
1928 |
|
|
|
1929 |
/* decreace the list */
|
|
|
1930 |
while (j < block_count) {
|
|
|
1931 |
blockLength[j - 1] = blockLength[j];
|
|
|
1932 |
blockType[j - 1] = blockType[j];
|
|
|
1933 |
j++;
|
|
|
1934 |
}
|
|
|
1935 |
block_count--;
|
|
|
1936 |
i--;
|
|
|
1937 |
}
|
|
|
1938 |
i++;
|
|
|
1939 |
}
|
|
|
1940 |
}
|
|
|
1941 |
|
|
|
1942 |
for (i = 0; i < block_count - 1; i++) {
|
|
|
1943 |
if (blockType[i] == GeneralFieldMode.NUMERIC && (blockLength[i] & 1) != 0) {
|
|
|
1944 |
/* Odd size numeric block */
|
|
|
1945 |
blockLength[i] = blockLength[i] - 1;
|
|
|
1946 |
blockLength[i + 1] = blockLength[i + 1] + 1;
|
|
|
1947 |
}
|
|
|
1948 |
}
|
|
|
1949 |
|
|
|
1950 |
j = 0;
|
|
|
1951 |
for (i = 0; i < block_count; i++) {
|
|
|
1952 |
for (k = 0; k < blockLength[i]; k++) {
|
|
|
1953 |
this.general_field_type[j] = blockType[i];
|
|
|
1954 |
j++;
|
|
|
1955 |
}
|
|
|
1956 |
}
|
|
|
1957 |
|
|
|
1958 |
if (blockType[block_count - 1] == GeneralFieldMode.NUMERIC && (blockLength[block_count - 1] & 1) != 0) {
|
|
|
1959 |
/*
|
|
|
1960 |
* If the last block is numeric and an odd size, further processing needs to be done
|
|
|
1961 |
* outside this procedure
|
|
|
1962 |
*/
|
|
|
1963 |
return true;
|
|
|
1964 |
} else {
|
|
|
1965 |
return false;
|
|
|
1966 |
}
|
|
|
1967 |
}
|
|
|
1968 |
|
|
|
1969 |
private void cc_a() {
|
|
|
1970 |
/* CC-A 2D component */
|
|
|
1971 |
int i, strpos, segment, cwCnt, variant, rows;
|
|
|
1972 |
int k, offset, j, total;
|
|
|
1973 |
final int[] rsCodeWords = new int[8];
|
|
|
1974 |
int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster;
|
|
|
1975 |
int LeftRAP, RightRAP, CentreRAP, Cluster;
|
|
|
1976 |
final int[] dummy = new int[5];
|
|
|
1977 |
int flip, loop;
|
|
|
1978 |
String codebarre;
|
|
|
1979 |
final StringBuilder bin = new StringBuilder();
|
|
|
1980 |
String local_source; /* A copy of source but with padding zeroes to make 208 bits */
|
|
|
1981 |
|
|
|
1982 |
variant = 0;
|
|
|
1983 |
|
|
|
1984 |
for (i = 0; i < 13; i++) {
|
|
|
1985 |
this.bitStr[i] = 0;
|
|
|
1986 |
}
|
|
|
1987 |
for (i = 0; i < 28; i++) {
|
|
|
1988 |
this.codeWords[i] = 0;
|
|
|
1989 |
}
|
|
|
1990 |
|
|
|
1991 |
local_source = this.binary_string;
|
|
|
1992 |
for (i = this.binary_string.length(); i < 208; i++) {
|
|
|
1993 |
local_source += "0";
|
|
|
1994 |
}
|
|
|
1995 |
|
|
|
1996 |
for (segment = 0; segment < 13; segment++) {
|
|
|
1997 |
strpos = segment * 16;
|
|
|
1998 |
this.bitStr[segment] = 0;
|
|
|
1999 |
for (i = 0; i < 16; i++) {
|
|
|
2000 |
if (local_source.charAt(strpos + i) == '1') {
|
|
|
2001 |
this.bitStr[segment] += 0x8000 >> i;
|
|
|
2002 |
}
|
|
|
2003 |
}
|
|
|
2004 |
}
|
|
|
2005 |
|
|
|
2006 |
init928();
|
|
|
2007 |
/* encode codeWords from bitStr */
|
|
|
2008 |
cwCnt = encode928(this.binary_string.length());
|
|
|
2009 |
|
|
|
2010 |
switch (this.cc_width) {
|
|
|
2011 |
case 2:
|
|
|
2012 |
switch (cwCnt) {
|
|
|
2013 |
case 6:
|
|
|
2014 |
variant = 0;
|
|
|
2015 |
break;
|
|
|
2016 |
case 8:
|
|
|
2017 |
variant = 1;
|
|
|
2018 |
break;
|
|
|
2019 |
case 9:
|
|
|
2020 |
variant = 2;
|
|
|
2021 |
break;
|
|
|
2022 |
case 11:
|
|
|
2023 |
variant = 3;
|
|
|
2024 |
break;
|
|
|
2025 |
case 12:
|
|
|
2026 |
variant = 4;
|
|
|
2027 |
break;
|
|
|
2028 |
case 14:
|
|
|
2029 |
variant = 5;
|
|
|
2030 |
break;
|
|
|
2031 |
case 17:
|
|
|
2032 |
variant = 6;
|
|
|
2033 |
break;
|
|
|
2034 |
}
|
|
|
2035 |
break;
|
|
|
2036 |
case 3:
|
|
|
2037 |
switch (cwCnt) {
|
|
|
2038 |
case 8:
|
|
|
2039 |
variant = 7;
|
|
|
2040 |
break;
|
|
|
2041 |
case 10:
|
|
|
2042 |
variant = 8;
|
|
|
2043 |
break;
|
|
|
2044 |
case 12:
|
|
|
2045 |
variant = 9;
|
|
|
2046 |
break;
|
|
|
2047 |
case 14:
|
|
|
2048 |
variant = 10;
|
|
|
2049 |
break;
|
|
|
2050 |
case 17:
|
|
|
2051 |
variant = 11;
|
|
|
2052 |
break;
|
|
|
2053 |
}
|
|
|
2054 |
break;
|
|
|
2055 |
case 4:
|
|
|
2056 |
switch (cwCnt) {
|
|
|
2057 |
case 8:
|
|
|
2058 |
variant = 12;
|
|
|
2059 |
break;
|
|
|
2060 |
case 11:
|
|
|
2061 |
variant = 13;
|
|
|
2062 |
break;
|
|
|
2063 |
case 14:
|
|
|
2064 |
variant = 14;
|
|
|
2065 |
break;
|
|
|
2066 |
case 17:
|
|
|
2067 |
variant = 15;
|
|
|
2068 |
break;
|
|
|
2069 |
case 20:
|
|
|
2070 |
variant = 16;
|
|
|
2071 |
break;
|
|
|
2072 |
}
|
|
|
2073 |
break;
|
|
|
2074 |
}
|
|
|
2075 |
|
|
|
2076 |
rows = CCA_VARIANTS[variant];
|
|
|
2077 |
k = CCA_VARIANTS[17 + variant];
|
|
|
2078 |
offset = CCA_VARIANTS[34 + variant];
|
|
|
2079 |
|
|
|
2080 |
/* Reed-Solomon error correction */
|
|
|
2081 |
|
|
|
2082 |
for (i = 0; i < 8; i++) {
|
|
|
2083 |
rsCodeWords[i] = 0;
|
|
|
2084 |
}
|
|
|
2085 |
total = 0;
|
|
|
2086 |
info("Composite Codewords: ");
|
|
|
2087 |
for (i = 0; i < cwCnt; i++) {
|
|
|
2088 |
total = (this.codeWords[i] + rsCodeWords[k - 1]) % 929;
|
|
|
2089 |
for (j = k - 1; j >= 0; j--) {
|
|
|
2090 |
if (j == 0) {
|
|
|
2091 |
rsCodeWords[j] = (929 - total * CCA_COEFFS[offset + j] % 929) % 929;
|
|
|
2092 |
} else {
|
|
|
2093 |
rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - total * CCA_COEFFS[offset + j] % 929) % 929;
|
|
|
2094 |
}
|
|
|
2095 |
}
|
|
|
2096 |
infoSpace(this.codeWords[i]);
|
|
|
2097 |
}
|
|
|
2098 |
infoLine();
|
|
|
2099 |
|
|
|
2100 |
for (j = 0; j < k; j++) {
|
|
|
2101 |
if (rsCodeWords[j] != 0) {
|
|
|
2102 |
rsCodeWords[j] = 929 - rsCodeWords[j];
|
|
|
2103 |
}
|
|
|
2104 |
}
|
|
|
2105 |
|
|
|
2106 |
for (i = k - 1; i >= 0; i--) {
|
|
|
2107 |
this.codeWords[cwCnt] = rsCodeWords[i];
|
|
|
2108 |
cwCnt++;
|
|
|
2109 |
}
|
|
|
2110 |
|
|
|
2111 |
/* Place data into table */
|
|
|
2112 |
LeftRAPStart = A_RAP_TABLE[variant];
|
|
|
2113 |
CentreRAPStart = A_RAP_TABLE[variant + 17];
|
|
|
2114 |
RightRAPStart = A_RAP_TABLE[variant + 34];
|
|
|
2115 |
StartCluster = A_RAP_TABLE[variant + 51] / 3;
|
|
|
2116 |
|
|
|
2117 |
LeftRAP = LeftRAPStart;
|
|
|
2118 |
CentreRAP = CentreRAPStart;
|
|
|
2119 |
RightRAP = RightRAPStart;
|
|
|
2120 |
Cluster = StartCluster; /*
|
|
|
2121 |
* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and
|
|
|
2122 |
* Cluster(6)
|
|
|
2123 |
*/
|
|
|
2124 |
|
|
|
2125 |
this.readable = "";
|
|
|
2126 |
this.row_count = rows;
|
|
|
2127 |
this.pattern = new String[this.row_count];
|
|
|
2128 |
this.row_height = new int[this.row_count];
|
|
|
2129 |
|
|
|
2130 |
for (i = 0; i < rows; i++) {
|
|
|
2131 |
codebarre = "";
|
|
|
2132 |
offset = 929 * Cluster;
|
|
|
2133 |
for (j = 0; j < 5; j++) {
|
|
|
2134 |
dummy[j] = 0;
|
|
|
2135 |
}
|
|
|
2136 |
for (j = 0; j < this.cc_width; j++) {
|
|
|
2137 |
dummy[j + 1] = this.codeWords[i * this.cc_width + j];
|
|
|
2138 |
}
|
|
|
2139 |
/* Copy the data into codebarre */
|
|
|
2140 |
codebarre += RAPLR[LeftRAP];
|
|
|
2141 |
codebarre += "1";
|
|
|
2142 |
codebarre += CODAGEMC[offset + dummy[1]];
|
|
|
2143 |
codebarre += "1";
|
|
|
2144 |
if (this.cc_width == 3) {
|
|
|
2145 |
codebarre += RAPC[CentreRAP];
|
|
|
2146 |
}
|
|
|
2147 |
if (this.cc_width >= 2) {
|
|
|
2148 |
codebarre += "1";
|
|
|
2149 |
codebarre += CODAGEMC[offset + dummy[2]];
|
|
|
2150 |
codebarre += "1";
|
|
|
2151 |
}
|
|
|
2152 |
if (this.cc_width == 4) {
|
|
|
2153 |
codebarre += RAPC[CentreRAP];
|
|
|
2154 |
}
|
|
|
2155 |
if (this.cc_width >= 3) {
|
|
|
2156 |
codebarre += "1";
|
|
|
2157 |
codebarre += CODAGEMC[offset + dummy[3]];
|
|
|
2158 |
codebarre += "1";
|
|
|
2159 |
}
|
|
|
2160 |
if (this.cc_width == 4) {
|
|
|
2161 |
codebarre += "1";
|
|
|
2162 |
codebarre += CODAGEMC[offset + dummy[4]];
|
|
|
2163 |
codebarre += "1";
|
|
|
2164 |
}
|
|
|
2165 |
codebarre += RAPLR[RightRAP];
|
|
|
2166 |
codebarre += "1"; /* stop */
|
|
|
2167 |
|
|
|
2168 |
/* Now codebarre is a mixture of letters and numbers */
|
|
|
2169 |
|
|
|
2170 |
flip = 1;
|
|
|
2171 |
bin.setLength(0);
|
|
|
2172 |
for (loop = 0; loop < codebarre.length(); loop++) {
|
|
|
2173 |
if (codebarre.charAt(loop) >= '0' && codebarre.charAt(loop) <= '9') {
|
|
|
2174 |
for (k = 0; k < codebarre.charAt(loop) - '0'; k++) {
|
|
|
2175 |
if (flip == 0) {
|
|
|
2176 |
bin.append('0');
|
|
|
2177 |
} else {
|
|
|
2178 |
bin.append('1');
|
|
|
2179 |
}
|
|
|
2180 |
}
|
|
|
2181 |
if (flip == 0) {
|
|
|
2182 |
flip = 1;
|
|
|
2183 |
} else {
|
|
|
2184 |
flip = 0;
|
|
|
2185 |
}
|
|
|
2186 |
} else {
|
|
|
2187 |
bin.append(PDF_TTF[positionOf(codebarre.charAt(loop), BR_SET)]);
|
|
|
2188 |
}
|
|
|
2189 |
}
|
|
|
2190 |
|
|
|
2191 |
this.row_height[i] = 2;
|
|
|
2192 |
this.pattern[i] = bin2pat(bin);
|
|
|
2193 |
|
|
|
2194 |
/* Set up RAPs and Cluster for next row */
|
|
|
2195 |
LeftRAP++;
|
|
|
2196 |
CentreRAP++;
|
|
|
2197 |
RightRAP++;
|
|
|
2198 |
Cluster++;
|
|
|
2199 |
|
|
|
2200 |
if (LeftRAP == 53) {
|
|
|
2201 |
LeftRAP = 1;
|
|
|
2202 |
}
|
|
|
2203 |
if (CentreRAP == 53) {
|
|
|
2204 |
CentreRAP = 1;
|
|
|
2205 |
}
|
|
|
2206 |
if (RightRAP == 53) {
|
|
|
2207 |
RightRAP = 1;
|
|
|
2208 |
}
|
|
|
2209 |
if (Cluster == 3) {
|
|
|
2210 |
Cluster = 0;
|
|
|
2211 |
}
|
|
|
2212 |
}
|
|
|
2213 |
}
|
|
|
2214 |
|
|
|
2215 |
/* initialize pwr928 encoding table */
|
|
|
2216 |
private void init928() {
|
|
|
2217 |
int i, j, v;
|
|
|
2218 |
final int[] cw = new int[7];
|
|
|
2219 |
cw[6] = 1;
|
|
|
2220 |
for (i = 5; i >= 0; i--) {
|
|
|
2221 |
cw[i] = 0;
|
|
|
2222 |
}
|
|
|
2223 |
|
|
|
2224 |
for (i = 0; i < 7; i++) {
|
|
|
2225 |
this.pwr928[0][i] = cw[i];
|
|
|
2226 |
}
|
|
|
2227 |
for (j = 1; j < 69; j++) {
|
|
|
2228 |
for (v = 0, i = 6; i >= 1; i--) {
|
|
|
2229 |
v = 2 * cw[i] + v / 928;
|
|
|
2230 |
this.pwr928[j][i] = cw[i] = v % 928;
|
|
|
2231 |
}
|
|
|
2232 |
this.pwr928[j][0] = cw[0] = 2 * cw[0] + v / 928;
|
|
|
2233 |
}
|
|
|
2234 |
}
|
|
|
2235 |
|
|
|
2236 |
/* converts bit string to base 928 values, codeWords[0] is highest order */
|
|
|
2237 |
private int encode928(final int bitLng) {
|
|
|
2238 |
int i, j, b, bitCnt, cwNdx, cwCnt, cwLng;
|
|
|
2239 |
for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) {
|
|
|
2240 |
bitCnt = min(bitLng - b, 69);
|
|
|
2241 |
cwLng += cwCnt = bitCnt / 10 + 1;
|
|
|
2242 |
for (i = 0; i < cwCnt; i++) {
|
|
|
2243 |
this.codeWords[cwNdx + i] = 0; /* init 0 */
|
|
|
2244 |
}
|
|
|
2245 |
for (i = 0; i < bitCnt; i++) {
|
|
|
2246 |
if (getBit(b + bitCnt - i - 1)) {
|
|
|
2247 |
for (j = 0; j < cwCnt; j++) {
|
|
|
2248 |
this.codeWords[cwNdx + j] += this.pwr928[i][j + 7 - cwCnt];
|
|
|
2249 |
}
|
|
|
2250 |
}
|
|
|
2251 |
}
|
|
|
2252 |
for (i = cwCnt - 1; i > 0; i--) {
|
|
|
2253 |
/* add "carries" */
|
|
|
2254 |
this.codeWords[cwNdx + i - 1] += this.codeWords[cwNdx + i] / 928;
|
|
|
2255 |
this.codeWords[cwNdx + i] %= 928;
|
|
|
2256 |
}
|
|
|
2257 |
}
|
|
|
2258 |
return cwLng;
|
|
|
2259 |
}
|
|
|
2260 |
|
|
|
2261 |
private int min(final int first, final int second) {
|
|
|
2262 |
if (first <= second) {
|
|
|
2263 |
return first;
|
|
|
2264 |
} else {
|
|
|
2265 |
return second;
|
|
|
2266 |
}
|
|
|
2267 |
}
|
|
|
2268 |
|
|
|
2269 |
/* gets bit in bitString at bitPos */
|
|
|
2270 |
private boolean getBit(final int arg) {
|
|
|
2271 |
if ((this.bitStr[arg >> 4] & 0x8000 >> (arg & 15)) != 0) {
|
|
|
2272 |
return true;
|
|
|
2273 |
} else {
|
|
|
2274 |
return false;
|
|
|
2275 |
}
|
|
|
2276 |
}
|
|
|
2277 |
|
|
|
2278 |
private void cc_b() {
|
|
|
2279 |
/* CC-B 2D component */
|
|
|
2280 |
int length, i, binloc;
|
|
|
2281 |
int k, j, longueur, offset;
|
|
|
2282 |
final int[] mccorrection = new int[50];
|
|
|
2283 |
int total;
|
|
|
2284 |
final int[] dummy = new int[5];
|
|
|
2285 |
String codebarre;
|
|
|
2286 |
final StringBuilder bin = new StringBuilder();
|
|
|
2287 |
int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster;
|
|
|
2288 |
int LeftRAP, CentreRAP, RightRAP, Cluster, flip, loop;
|
|
|
2289 |
int option_2, rows;
|
|
|
2290 |
this.inputData = new int[this.binary_string.length() / 8 + 3];
|
|
|
2291 |
|
|
|
2292 |
length = this.binary_string.length() / 8;
|
|
|
2293 |
|
|
|
2294 |
for (i = 0; i < length; i++) {
|
|
|
2295 |
binloc = i * 8;
|
|
|
2296 |
|
|
|
2297 |
this.inputData[i] = 0;
|
|
|
2298 |
for (j = 0; j < 8; j++) {
|
|
|
2299 |
if (this.binary_string.charAt(binloc + j) == '1') {
|
|
|
2300 |
this.inputData[i] += 0x80 >> j;
|
|
|
2301 |
}
|
|
|
2302 |
}
|
|
|
2303 |
}
|
|
|
2304 |
|
|
|
2305 |
this.codeWordCount = 0;
|
|
|
2306 |
|
|
|
2307 |
/*
|
|
|
2308 |
* "the CC-B component shall have codeword 920 in the first symbol character position"
|
|
|
2309 |
* (section 9a)
|
|
|
2310 |
*/
|
|
|
2311 |
this.codeWords[this.codeWordCount] = 920;
|
|
|
2312 |
this.codeWordCount++;
|
|
|
2313 |
|
|
|
2314 |
byteprocess(0, length);
|
|
|
2315 |
|
|
|
2316 |
/* Now figure out which variant of the symbol to use and load values accordingly */
|
|
|
2317 |
|
|
|
2318 |
variant = 0;
|
|
|
2319 |
|
|
|
2320 |
if (this.cc_width == 2) {
|
|
|
2321 |
variant = 13;
|
|
|
2322 |
if (this.codeWordCount <= 33) {
|
|
|
2323 |
variant = 12;
|
|
|
2324 |
}
|
|
|
2325 |
if (this.codeWordCount <= 29) {
|
|
|
2326 |
variant = 11;
|
|
|
2327 |
}
|
|
|
2328 |
if (this.codeWordCount <= 24) {
|
|
|
2329 |
variant = 10;
|
|
|
2330 |
}
|
|
|
2331 |
if (this.codeWordCount <= 19) {
|
|
|
2332 |
variant = 9;
|
|
|
2333 |
}
|
|
|
2334 |
if (this.codeWordCount <= 13) {
|
|
|
2335 |
variant = 8;
|
|
|
2336 |
}
|
|
|
2337 |
if (this.codeWordCount <= 8) {
|
|
|
2338 |
variant = 7;
|
|
|
2339 |
}
|
|
|
2340 |
}
|
|
|
2341 |
|
|
|
2342 |
if (this.cc_width == 3) {
|
|
|
2343 |
variant = 23;
|
|
|
2344 |
if (this.codeWordCount <= 70) {
|
|
|
2345 |
variant = 22;
|
|
|
2346 |
}
|
|
|
2347 |
if (this.codeWordCount <= 58) {
|
|
|
2348 |
variant = 21;
|
|
|
2349 |
}
|
|
|
2350 |
if (this.codeWordCount <= 46) {
|
|
|
2351 |
variant = 20;
|
|
|
2352 |
}
|
|
|
2353 |
if (this.codeWordCount <= 34) {
|
|
|
2354 |
variant = 19;
|
|
|
2355 |
}
|
|
|
2356 |
if (this.codeWordCount <= 24) {
|
|
|
2357 |
variant = 18;
|
|
|
2358 |
}
|
|
|
2359 |
if (this.codeWordCount <= 18) {
|
|
|
2360 |
variant = 17;
|
|
|
2361 |
}
|
|
|
2362 |
if (this.codeWordCount <= 14) {
|
|
|
2363 |
variant = 16;
|
|
|
2364 |
}
|
|
|
2365 |
if (this.codeWordCount <= 10) {
|
|
|
2366 |
variant = 15;
|
|
|
2367 |
}
|
|
|
2368 |
if (this.codeWordCount <= 6) {
|
|
|
2369 |
variant = 14;
|
|
|
2370 |
}
|
|
|
2371 |
}
|
|
|
2372 |
|
|
|
2373 |
if (this.cc_width == 4) {
|
|
|
2374 |
variant = 34;
|
|
|
2375 |
if (this.codeWordCount <= 108) {
|
|
|
2376 |
variant = 33;
|
|
|
2377 |
}
|
|
|
2378 |
if (this.codeWordCount <= 90) {
|
|
|
2379 |
variant = 32;
|
|
|
2380 |
}
|
|
|
2381 |
if (this.codeWordCount <= 72) {
|
|
|
2382 |
variant = 31;
|
|
|
2383 |
}
|
|
|
2384 |
if (this.codeWordCount <= 54) {
|
|
|
2385 |
variant = 30;
|
|
|
2386 |
}
|
|
|
2387 |
if (this.codeWordCount <= 39) {
|
|
|
2388 |
variant = 29;
|
|
|
2389 |
}
|
|
|
2390 |
if (this.codeWordCount <= 30) {
|
|
|
2391 |
variant = 28;
|
|
|
2392 |
}
|
|
|
2393 |
if (this.codeWordCount <= 24) {
|
|
|
2394 |
variant = 27;
|
|
|
2395 |
}
|
|
|
2396 |
if (this.codeWordCount <= 18) {
|
|
|
2397 |
variant = 26;
|
|
|
2398 |
}
|
|
|
2399 |
if (this.codeWordCount <= 12) {
|
|
|
2400 |
variant = 25;
|
|
|
2401 |
}
|
|
|
2402 |
if (this.codeWordCount <= 8) {
|
|
|
2403 |
variant = 24;
|
|
|
2404 |
}
|
|
|
2405 |
}
|
|
|
2406 |
|
|
|
2407 |
/*
|
|
|
2408 |
* Now we have the variant we can load the data - from here on the same as MicroPDF417 code
|
|
|
2409 |
*/
|
|
|
2410 |
variant--;
|
|
|
2411 |
option_2 = MICRO_VARIANTS[variant]; /* columns */
|
|
|
2412 |
rows = MICRO_VARIANTS[variant + 34]; /* rows */
|
|
|
2413 |
k = MICRO_VARIANTS[variant + 68]; /* number of EC CWs */
|
|
|
2414 |
longueur = option_2 * rows - k; /* number of non-EC CWs */
|
|
|
2415 |
i = longueur - this.codeWordCount; /* amount of padding required */
|
|
|
2416 |
offset = MICRO_VARIANTS[variant + 102]; /* coefficient offset */
|
|
|
2417 |
|
|
|
2418 |
/* We add the padding */
|
|
|
2419 |
while (i > 0) {
|
|
|
2420 |
this.codeWords[this.codeWordCount] = 900;
|
|
|
2421 |
this.codeWordCount++;
|
|
|
2422 |
i--;
|
|
|
2423 |
}
|
|
|
2424 |
|
|
|
2425 |
/* Reed-Solomon error correction */
|
|
|
2426 |
longueur = this.codeWordCount;
|
|
|
2427 |
for (loop = 0; loop < 50; loop++) {
|
|
|
2428 |
mccorrection[loop] = 0;
|
|
|
2429 |
}
|
|
|
2430 |
total = 0;
|
|
|
2431 |
info("Composite Codewords: ");
|
|
|
2432 |
for (i = 0; i < longueur; i++) {
|
|
|
2433 |
total = (this.codeWords[i] + mccorrection[k - 1]) % 929;
|
|
|
2434 |
for (j = k - 1; j >= 0; j--) {
|
|
|
2435 |
if (j == 0) {
|
|
|
2436 |
mccorrection[j] = (929 - total * MICROCOEFFS[offset + j] % 929) % 929;
|
|
|
2437 |
} else {
|
|
|
2438 |
mccorrection[j] = (mccorrection[j - 1] + 929 - total * MICROCOEFFS[offset + j] % 929) % 929;
|
|
|
2439 |
}
|
|
|
2440 |
}
|
|
|
2441 |
infoSpace(this.codeWords[i]);
|
|
|
2442 |
}
|
|
|
2443 |
infoLine();
|
|
|
2444 |
|
|
|
2445 |
for (j = 0; j < k; j++) {
|
|
|
2446 |
if (mccorrection[j] != 0) {
|
|
|
2447 |
mccorrection[j] = 929 - mccorrection[j];
|
|
|
2448 |
}
|
|
|
2449 |
}
|
|
|
2450 |
/* we add these codes to the string */
|
|
|
2451 |
for (i = k - 1; i >= 0; i--) {
|
|
|
2452 |
this.codeWords[this.codeWordCount] = mccorrection[i];
|
|
|
2453 |
this.codeWordCount++;
|
|
|
2454 |
}
|
|
|
2455 |
|
|
|
2456 |
/* Now get the RAP (Row Address Pattern) start values */
|
|
|
2457 |
LeftRAPStart = RAP_TABLE[variant];
|
|
|
2458 |
CentreRAPStart = RAP_TABLE[variant + 34];
|
|
|
2459 |
RightRAPStart = RAP_TABLE[variant + 68];
|
|
|
2460 |
StartCluster = RAP_TABLE[variant + 102] / 3;
|
|
|
2461 |
|
|
|
2462 |
/* That's all values loaded, get on with the encoding */
|
|
|
2463 |
|
|
|
2464 |
LeftRAP = LeftRAPStart;
|
|
|
2465 |
CentreRAP = CentreRAPStart;
|
|
|
2466 |
RightRAP = RightRAPStart;
|
|
|
2467 |
Cluster = StartCluster; /*
|
|
|
2468 |
* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and
|
|
|
2469 |
* Cluster(6)
|
|
|
2470 |
*/
|
|
|
2471 |
|
|
|
2472 |
this.readable = "";
|
|
|
2473 |
this.row_count = rows;
|
|
|
2474 |
this.pattern = new String[this.row_count];
|
|
|
2475 |
this.row_height = new int[this.row_count];
|
|
|
2476 |
|
|
|
2477 |
for (i = 0; i < rows; i++) {
|
|
|
2478 |
codebarre = "";
|
|
|
2479 |
offset = 929 * Cluster;
|
|
|
2480 |
for (j = 0; j < 5; j++) {
|
|
|
2481 |
dummy[j] = 0;
|
|
|
2482 |
}
|
|
|
2483 |
for (j = 0; j < option_2; j++) {
|
|
|
2484 |
dummy[j + 1] = this.codeWords[i * option_2 + j];
|
|
|
2485 |
}
|
|
|
2486 |
/* Copy the data into codebarre */
|
|
|
2487 |
codebarre += RAPLR[LeftRAP];
|
|
|
2488 |
codebarre += "1";
|
|
|
2489 |
codebarre += CODAGEMC[offset + dummy[1]];
|
|
|
2490 |
codebarre += "1";
|
|
|
2491 |
if (this.cc_width == 3) {
|
|
|
2492 |
codebarre += RAPC[CentreRAP];
|
|
|
2493 |
}
|
|
|
2494 |
if (this.cc_width >= 2) {
|
|
|
2495 |
codebarre += "1";
|
|
|
2496 |
codebarre += CODAGEMC[offset + dummy[2]];
|
|
|
2497 |
codebarre += "1";
|
|
|
2498 |
}
|
|
|
2499 |
if (this.cc_width == 4) {
|
|
|
2500 |
codebarre += RAPC[CentreRAP];
|
|
|
2501 |
}
|
|
|
2502 |
if (this.cc_width >= 3) {
|
|
|
2503 |
codebarre += "1";
|
|
|
2504 |
codebarre += CODAGEMC[offset + dummy[3]];
|
|
|
2505 |
codebarre += "1";
|
|
|
2506 |
}
|
|
|
2507 |
if (this.cc_width == 4) {
|
|
|
2508 |
codebarre += "1";
|
|
|
2509 |
codebarre += CODAGEMC[offset + dummy[4]];
|
|
|
2510 |
codebarre += "1";
|
|
|
2511 |
}
|
|
|
2512 |
codebarre += RAPLR[RightRAP];
|
|
|
2513 |
codebarre += "1"; /* stop */
|
|
|
2514 |
|
|
|
2515 |
/* Now codebarre is a mixture of letters and numbers */
|
|
|
2516 |
|
|
|
2517 |
flip = 1;
|
|
|
2518 |
bin.setLength(0);
|
|
|
2519 |
for (loop = 0; loop < codebarre.length(); loop++) {
|
|
|
2520 |
if (codebarre.charAt(loop) >= '0' && codebarre.charAt(loop) <= '9') {
|
|
|
2521 |
for (k = 0; k < codebarre.charAt(loop) - '0'; k++) {
|
|
|
2522 |
if (flip == 0) {
|
|
|
2523 |
bin.append('0');
|
|
|
2524 |
} else {
|
|
|
2525 |
bin.append('1');
|
|
|
2526 |
}
|
|
|
2527 |
}
|
|
|
2528 |
if (flip == 0) {
|
|
|
2529 |
flip = 1;
|
|
|
2530 |
} else {
|
|
|
2531 |
flip = 0;
|
|
|
2532 |
}
|
|
|
2533 |
} else {
|
|
|
2534 |
bin.append(PDF_TTF[positionOf(codebarre.charAt(loop), BR_SET)]);
|
|
|
2535 |
}
|
|
|
2536 |
}
|
|
|
2537 |
|
|
|
2538 |
this.pattern[i] = bin2pat(bin);
|
|
|
2539 |
this.row_height[i] = 2;
|
|
|
2540 |
|
|
|
2541 |
/* Set up RAPs and Cluster for next row */
|
|
|
2542 |
LeftRAP++;
|
|
|
2543 |
CentreRAP++;
|
|
|
2544 |
RightRAP++;
|
|
|
2545 |
Cluster++;
|
|
|
2546 |
|
|
|
2547 |
if (LeftRAP == 53) {
|
|
|
2548 |
LeftRAP = 1;
|
|
|
2549 |
}
|
|
|
2550 |
if (CentreRAP == 53) {
|
|
|
2551 |
CentreRAP = 1;
|
|
|
2552 |
}
|
|
|
2553 |
if (RightRAP == 53) {
|
|
|
2554 |
RightRAP = 1;
|
|
|
2555 |
}
|
|
|
2556 |
if (Cluster == 3) {
|
|
|
2557 |
Cluster = 0;
|
|
|
2558 |
}
|
|
|
2559 |
|
|
|
2560 |
}
|
|
|
2561 |
}
|
|
|
2562 |
|
|
|
2563 |
private void cc_c() {
|
|
|
2564 |
/* CC-C 2D component - byte compressed PDF417 */
|
|
|
2565 |
int length, i, binloc, k;
|
|
|
2566 |
int offset, longueur, loop, total, j;
|
|
|
2567 |
final int[] mccorrection = new int[520];
|
|
|
2568 |
int c1, c2, c3;
|
|
|
2569 |
final int[] dummy = new int[35];
|
|
|
2570 |
String codebarre;
|
|
|
2571 |
final StringBuilder bin = new StringBuilder();
|
|
|
2572 |
this.inputData = new int[this.binary_string.length() / 8 + 4];
|
|
|
2573 |
|
|
|
2574 |
length = this.binary_string.length() / 8;
|
|
|
2575 |
|
|
|
2576 |
for (i = 0; i < length; i++) {
|
|
|
2577 |
binloc = i * 8;
|
|
|
2578 |
this.inputData[i] = 0;
|
|
|
2579 |
for (j = 0; j < 8; j++) {
|
|
|
2580 |
if (this.binary_string.charAt(binloc + j) == '1') {
|
|
|
2581 |
this.inputData[i] += 0x80 >> j;
|
|
|
2582 |
}
|
|
|
2583 |
}
|
|
|
2584 |
}
|
|
|
2585 |
|
|
|
2586 |
this.codeWordCount = 0;
|
|
|
2587 |
this.codeWords[this.codeWordCount] = 0; /* space for length descriptor */
|
|
|
2588 |
this.codeWordCount++;
|
|
|
2589 |
this.codeWords[this.codeWordCount] = 920; /* CC-C identifier */
|
|
|
2590 |
this.codeWordCount++;
|
|
|
2591 |
|
|
|
2592 |
byteprocess(0, length);
|
|
|
2593 |
|
|
|
2594 |
this.codeWords[0] = this.codeWordCount;
|
|
|
2595 |
|
|
|
2596 |
k = 1;
|
|
|
2597 |
for (i = 1; i <= this.ecc + 1; i++) {
|
|
|
2598 |
k *= 2;
|
|
|
2599 |
}
|
|
|
2600 |
|
|
|
2601 |
/* 796 - we now take care of the Reed Solomon codes */
|
|
|
2602 |
switch (this.ecc) {
|
|
|
2603 |
case 1:
|
|
|
2604 |
offset = 2;
|
|
|
2605 |
break;
|
|
|
2606 |
case 2:
|
|
|
2607 |
offset = 6;
|
|
|
2608 |
break;
|
|
|
2609 |
case 3:
|
|
|
2610 |
offset = 14;
|
|
|
2611 |
break;
|
|
|
2612 |
case 4:
|
|
|
2613 |
offset = 30;
|
|
|
2614 |
break;
|
|
|
2615 |
case 5:
|
|
|
2616 |
offset = 62;
|
|
|
2617 |
break;
|
|
|
2618 |
case 6:
|
|
|
2619 |
offset = 126;
|
|
|
2620 |
break;
|
|
|
2621 |
case 7:
|
|
|
2622 |
offset = 254;
|
|
|
2623 |
break;
|
|
|
2624 |
case 8:
|
|
|
2625 |
offset = 510;
|
|
|
2626 |
break;
|
|
|
2627 |
default:
|
|
|
2628 |
offset = 0;
|
|
|
2629 |
break;
|
|
|
2630 |
}
|
|
|
2631 |
|
|
|
2632 |
longueur = this.codeWordCount;
|
|
|
2633 |
for (loop = 0; loop < 520; loop++) {
|
|
|
2634 |
mccorrection[loop] = 0;
|
|
|
2635 |
}
|
|
|
2636 |
total = 0;
|
|
|
2637 |
info("Composite Codewords: ");
|
|
|
2638 |
for (i = 0; i < longueur; i++) {
|
|
|
2639 |
total = (this.codeWords[i] + mccorrection[k - 1]) % 929;
|
|
|
2640 |
for (j = k - 1; j >= 0; j--) {
|
|
|
2641 |
if (j == 0) {
|
|
|
2642 |
mccorrection[j] = (929 - total * COEFRS[offset + j] % 929) % 929;
|
|
|
2643 |
} else {
|
|
|
2644 |
mccorrection[j] = (mccorrection[j - 1] + 929 - total * COEFRS[offset + j] % 929) % 929;
|
|
|
2645 |
}
|
|
|
2646 |
}
|
|
|
2647 |
infoSpace(this.codeWords[i]);
|
|
|
2648 |
}
|
|
|
2649 |
infoLine();
|
|
|
2650 |
|
|
|
2651 |
for (j = 0; j < k; j++) {
|
|
|
2652 |
if (mccorrection[j] != 0) {
|
|
|
2653 |
mccorrection[j] = 929 - mccorrection[j];
|
|
|
2654 |
}
|
|
|
2655 |
}
|
|
|
2656 |
/* we add these codes to the string */
|
|
|
2657 |
for (i = k - 1; i >= 0; i--) {
|
|
|
2658 |
this.codeWords[this.codeWordCount] = mccorrection[i];
|
|
|
2659 |
this.codeWordCount++;
|
|
|
2660 |
}
|
|
|
2661 |
|
|
|
2662 |
/* 818 - The CW string is finished */
|
|
|
2663 |
c1 = (this.codeWordCount / this.cc_width - 1) / 3;
|
|
|
2664 |
c2 = this.ecc * 3 + (this.codeWordCount / this.cc_width - 1) % 3;
|
|
|
2665 |
c3 = this.cc_width - 1;
|
|
|
2666 |
|
|
|
2667 |
this.readable = "";
|
|
|
2668 |
this.row_count = this.codeWordCount / this.cc_width;
|
|
|
2669 |
this.pattern = new String[this.row_count];
|
|
|
2670 |
this.row_height = new int[this.row_count];
|
|
|
2671 |
|
|
|
2672 |
/* we now encode each row */
|
|
|
2673 |
for (i = 0; i <= this.codeWordCount / this.cc_width - 1; i++) {
|
|
|
2674 |
for (j = 0; j < this.cc_width; j++) {
|
|
|
2675 |
dummy[j + 1] = this.codeWords[i * this.cc_width + j];
|
|
|
2676 |
}
|
|
|
2677 |
k = i / 3 * 30;
|
|
|
2678 |
switch (i % 3) {
|
|
|
2679 |
/*
|
|
|
2680 |
* follows this pattern from US Patent 5,243,655: Row 0: L0 (row #, # of rows) R0 (row
|
|
|
2681 |
* #, # of columns) Row 1: L1 (row #, security level) R1 (row #, # of rows) Row 2: L2
|
|
|
2682 |
* (row #, # of columns) R2 (row #, security level) Row 3: L3 (row #, # of rows) R3 (row
|
|
|
2683 |
* #, # of columns) etc.
|
|
|
2684 |
*/
|
|
|
2685 |
case 0:
|
|
|
2686 |
dummy[0] = k + c1;
|
|
|
2687 |
dummy[this.cc_width + 1] = k + c3;
|
|
|
2688 |
break;
|
|
|
2689 |
case 1:
|
|
|
2690 |
dummy[0] = k + c2;
|
|
|
2691 |
dummy[this.cc_width + 1] = k + c1;
|
|
|
2692 |
break;
|
|
|
2693 |
case 2:
|
|
|
2694 |
dummy[0] = k + c3;
|
|
|
2695 |
dummy[this.cc_width + 1] = k + c2;
|
|
|
2696 |
break;
|
|
|
2697 |
}
|
|
|
2698 |
codebarre = "+*"; /* Start with a start char and a separator */
|
|
|
2699 |
|
|
|
2700 |
for (j = 0; j <= this.cc_width + 1; j++) {
|
|
|
2701 |
switch (i % 3) {
|
|
|
2702 |
case 1:
|
|
|
2703 |
offset = 929;
|
|
|
2704 |
/* cluster(3) */ break;
|
|
|
2705 |
case 2:
|
|
|
2706 |
offset = 1858;
|
|
|
2707 |
/* cluster(6) */ break;
|
|
|
2708 |
default:
|
|
|
2709 |
offset = 0;
|
|
|
2710 |
/* cluster(0) */ break;
|
|
|
2711 |
}
|
|
|
2712 |
codebarre += CODAGEMC[offset + dummy[j]];
|
|
|
2713 |
codebarre += "*";
|
|
|
2714 |
}
|
|
|
2715 |
codebarre += "-";
|
|
|
2716 |
|
|
|
2717 |
bin.setLength(0);
|
|
|
2718 |
for (loop = 0; loop < codebarre.length(); loop++) {
|
|
|
2719 |
bin.append(PDF_TTF[positionOf(codebarre.charAt(loop), BR_SET)]);
|
|
|
2720 |
}
|
|
|
2721 |
this.pattern[i] = bin2pat(bin);
|
|
|
2722 |
this.row_height[i] = 3;
|
|
|
2723 |
}
|
|
|
2724 |
}
|
|
|
2725 |
|
|
|
2726 |
private void byteprocess(int start, final int length) {
|
|
|
2727 |
int len = 0;
|
|
|
2728 |
int chunkLen = 0;
|
|
|
2729 |
BigInteger mantisa;
|
|
|
2730 |
BigInteger total;
|
|
|
2731 |
BigInteger word;
|
|
|
2732 |
|
|
|
2733 |
/* select the switch for multiple of 6 bytes */
|
|
|
2734 |
if (this.binary_string.length() % 6 == 0) {
|
|
|
2735 |
this.codeWords[this.codeWordCount++] = 924;
|
|
|
2736 |
} else {
|
|
|
2737 |
this.codeWords[this.codeWordCount++] = 901;
|
|
|
2738 |
}
|
|
|
2739 |
|
|
|
2740 |
while (len < length) {
|
|
|
2741 |
chunkLen = length - len;
|
|
|
2742 |
if (6 <= chunkLen) /* Take groups of 6 */ {
|
|
|
2743 |
chunkLen = 6;
|
|
|
2744 |
len += chunkLen;
|
|
|
2745 |
total = BigInteger.valueOf(0);
|
|
|
2746 |
|
|
|
2747 |
while (chunkLen-- != 0) {
|
|
|
2748 |
mantisa = BigInteger.valueOf(this.inputData[start++]);
|
|
|
2749 |
total = total.or(mantisa.shiftLeft(chunkLen * 8));
|
|
|
2750 |
}
|
|
|
2751 |
|
|
|
2752 |
chunkLen = 5;
|
|
|
2753 |
|
|
|
2754 |
while (chunkLen-- != 0) {
|
|
|
2755 |
|
|
|
2756 |
word = total.mod(BigInteger.valueOf(900));
|
|
|
2757 |
this.codeWords[this.codeWordCount + chunkLen] = word.intValue();
|
|
|
2758 |
total = total.divide(BigInteger.valueOf(900));
|
|
|
2759 |
}
|
|
|
2760 |
this.codeWordCount += 5;
|
|
|
2761 |
} else /* If it remain a group of less than 6 bytes */ {
|
|
|
2762 |
len += chunkLen;
|
|
|
2763 |
while (chunkLen-- != 0) {
|
|
|
2764 |
this.codeWords[this.codeWordCount++] = this.inputData[start++];
|
|
|
2765 |
}
|
|
|
2766 |
}
|
|
|
2767 |
}
|
|
|
2768 |
}
|
|
|
2769 |
}
|