]> git.sur5r.net Git - glabels/blob - libglbarcode/lgl-barcode-onecode.c
Imported Upstream version 3.0.0
[glabels] / libglbarcode / lgl-barcode-onecode.c
1 /*
2  *  lgl-barcode-onecode.c
3  *  Copyright (C) 2010  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of libglbarcode.
6  *
7  *  libglbarcode is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  libglbarcode is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with libglbarcode.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * This module implements the Intelligent Mail (OneCode) barcode
23  * specified in the USPS specification USPS-B-3200E, 07/08/05.
24  */
25
26 #include <config.h>
27
28 #include "lgl-barcode-onecode.h"
29
30 #include <glib.h>
31 #include <ctype.h>
32 #include <string.h>
33
34 /*========================================================*/
35 /* Private macros and constants.                          */
36 /*========================================================*/
37
38 #define CHAR_A 0
39 #define CHAR_B 1
40 #define CHAR_C 2
41 #define CHAR_D 3
42 #define CHAR_E 4
43 #define CHAR_F 5
44 #define CHAR_G 6
45 #define CHAR_H 7
46 #define CHAR_I 8
47 #define CHAR_J 9
48
49 #define PTS_PER_INCH 72.0
50
51 #define ONECODE_BAR_WIDTH        ( 0.02   * PTS_PER_INCH )
52 #define ONECODE_FULL_HEIGHT      ( 0.145  * PTS_PER_INCH )
53 #define ONECODE_ASCENDER_HEIGHT  ( 0.0965 * PTS_PER_INCH )
54 #define ONECODE_DESCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH )
55 #define ONECODE_TRACKER_HEIGHT   ( 0.048  * PTS_PER_INCH )
56 #define ONECODE_FULL_OFFSET      0
57 #define ONECODE_ASCENDER_OFFSET  0
58 #define ONECODE_DESCENDER_OFFSET ( 0.0485 * PTS_PER_INCH )
59 #define ONECODE_TRACKER_OFFSET   ( 0.0485 * PTS_PER_INCH )
60 #define ONECODE_BAR_PITCH        ( 0.0458 * PTS_PER_INCH )
61 #define ONECODE_HORIZ_MARGIN     ( 0.125  * PTS_PER_INCH )
62 #define ONECODE_VERT_MARGIN      ( 0.028  * PTS_PER_INCH )
63
64
65 /*========================================================*/
66 /* Private types.                                         */
67 /*========================================================*/
68
69 typedef struct {
70         guchar byte[13];
71 } Int104;
72
73 typedef struct {
74         struct { gint i; gint mask; } descender;
75         struct { gint i; gint mask; } ascender;
76 } BarMapEntry;
77
78
79 /*===========================================*/
80 /* Private globals                           */
81 /*===========================================*/
82
83 static BarMapEntry bar_map[] = {
84         /*  1 */ { { CHAR_H, 1<<2  }, { CHAR_E, 1<<3  } },
85         /*  2 */ { { CHAR_B, 1<<10 }, { CHAR_A, 1<<0  } },
86         /*  3 */ { { CHAR_J, 1<<12 }, { CHAR_C, 1<<8  } },
87         /*  4 */ { { CHAR_F, 1<<5  }, { CHAR_G, 1<<11 } },
88         /*  5 */ { { CHAR_I, 1<<9  }, { CHAR_D, 1<<1  } },
89         /*  6 */ { { CHAR_A, 1<<1  }, { CHAR_F, 1<<12 } },
90         /*  7 */ { { CHAR_C, 1<<5  }, { CHAR_B, 1<<8  } },
91         /*  8 */ { { CHAR_E, 1<<4  }, { CHAR_J, 1<<11 } },
92         /*  9 */ { { CHAR_G, 1<<3  }, { CHAR_I, 1<<10 } },
93         /* 10 */ { { CHAR_D, 1<<9  }, { CHAR_H, 1<<6  } },
94         /* 11 */ { { CHAR_F, 1<<11 }, { CHAR_B, 1<<4  } },
95         /* 12 */ { { CHAR_I, 1<<5  }, { CHAR_C, 1<<12 } },
96         /* 13 */ { { CHAR_J, 1<<10 }, { CHAR_A, 1<<2  } },
97         /* 14 */ { { CHAR_H, 1<<1  }, { CHAR_G, 1<<7  } },
98         /* 15 */ { { CHAR_D, 1<<6  }, { CHAR_E, 1<<9  } },
99         /* 16 */ { { CHAR_A, 1<<3  }, { CHAR_I, 1<<6  } },
100         /* 17 */ { { CHAR_G, 1<<4  }, { CHAR_C, 1<<7  } },
101         /* 18 */ { { CHAR_B, 1<<1  }, { CHAR_J, 1<<9  } },
102         /* 19 */ { { CHAR_H, 1<<10 }, { CHAR_F, 1<<2  } },
103         /* 20 */ { { CHAR_E, 1<<0  }, { CHAR_D, 1<<8  } },
104         /* 21 */ { { CHAR_G, 1<<2  }, { CHAR_A, 1<<4  } },
105         /* 22 */ { { CHAR_I, 1<<11 }, { CHAR_B, 1<<0  } },
106         /* 23 */ { { CHAR_J, 1<<8  }, { CHAR_D, 1<<12 } },
107         /* 24 */ { { CHAR_C, 1<<6  }, { CHAR_H, 1<<7  } },
108         /* 25 */ { { CHAR_F, 1<<1  }, { CHAR_E, 1<<10 } },
109         /* 26 */ { { CHAR_B, 1<<12 }, { CHAR_G, 1<<9  } },
110         /* 27 */ { { CHAR_H, 1<<3  }, { CHAR_I, 1<<0  } },
111         /* 28 */ { { CHAR_F, 1<<8  }, { CHAR_J, 1<<7  } },
112         /* 29 */ { { CHAR_E, 1<<6  }, { CHAR_C, 1<<10 } },
113         /* 30 */ { { CHAR_D, 1<<4  }, { CHAR_A, 1<<5  } },
114         /* 31 */ { { CHAR_I, 1<<4  }, { CHAR_F, 1<<7  } },
115         /* 32 */ { { CHAR_H, 1<<11 }, { CHAR_B, 1<<9  } },
116         /* 33 */ { { CHAR_G, 1<<0  }, { CHAR_J, 1<<6  } },
117         /* 34 */ { { CHAR_A, 1<<6  }, { CHAR_E, 1<<8  } },
118         /* 35 */ { { CHAR_C, 1<<1  }, { CHAR_D, 1<<2  } },
119         /* 36 */ { { CHAR_F, 1<<9  }, { CHAR_I, 1<<12 } },
120         /* 37 */ { { CHAR_E, 1<<11 }, { CHAR_G, 1<<1  } },
121         /* 38 */ { { CHAR_J, 1<<5  }, { CHAR_H, 1<<4  } },
122         /* 39 */ { { CHAR_D, 1<<3  }, { CHAR_B, 1<<2  } },
123         /* 40 */ { { CHAR_A, 1<<7  }, { CHAR_C, 1<<0  } },
124         /* 41 */ { { CHAR_B, 1<<3  }, { CHAR_E, 1<<1  } },
125         /* 42 */ { { CHAR_G, 1<<10 }, { CHAR_D, 1<<5  } },
126         /* 43 */ { { CHAR_I, 1<<7  }, { CHAR_J, 1<<4  } },
127         /* 44 */ { { CHAR_C, 1<<11 }, { CHAR_F, 1<<6  } },
128         /* 45 */ { { CHAR_A, 1<<8  }, { CHAR_H, 1<<12 } },
129         /* 46 */ { { CHAR_E, 1<<2  }, { CHAR_I, 1<<1  } },
130         /* 47 */ { { CHAR_F, 1<<10 }, { CHAR_D, 1<<0  } },
131         /* 48 */ { { CHAR_J, 1<<3  }, { CHAR_A, 1<<9  } },
132         /* 49 */ { { CHAR_G, 1<<5  }, { CHAR_C, 1<<4  } },
133         /* 50 */ { { CHAR_H, 1<<8  }, { CHAR_B, 1<<7  } },
134         /* 51 */ { { CHAR_F, 1<<0  }, { CHAR_E, 1<<5  } },
135         /* 52 */ { { CHAR_C, 1<<3  }, { CHAR_A, 1<<10 } },
136         /* 53 */ { { CHAR_G, 1<<12 }, { CHAR_J, 1<<2  } },
137         /* 54 */ { { CHAR_D, 1<<11 }, { CHAR_B, 1<<6  } },
138         /* 55 */ { { CHAR_I, 1<<8  }, { CHAR_H, 1<<9  } },
139         /* 56 */ { { CHAR_F, 1<<4  }, { CHAR_A, 1<<11 } },
140         /* 57 */ { { CHAR_B, 1<<5  }, { CHAR_C, 1<<2  } },
141         /* 58 */ { { CHAR_J, 1<<1  }, { CHAR_E, 1<<12 } },
142         /* 59 */ { { CHAR_I, 1<<3  }, { CHAR_G, 1<<6  } },
143         /* 60 */ { { CHAR_H, 1<<0  }, { CHAR_D, 1<<7  } },
144         /* 61 */ { { CHAR_E, 1<<7  }, { CHAR_H, 1<<5  } },
145         /* 62 */ { { CHAR_A, 1<<12 }, { CHAR_B, 1<<11 } },
146         /* 63 */ { { CHAR_C, 1<<9  }, { CHAR_J, 1<<0  } },
147         /* 64 */ { { CHAR_G, 1<<8  }, { CHAR_F, 1<<3  } },
148         /* 65 */ { { CHAR_D, 1<<10 }, { CHAR_I, 1<<2  } }
149 };
150
151 static gchar * tdaf_table[4] = { "T", "D", "A", "F" };
152
153 static guint character_table[] = {
154         /* Table I 5 of 13. */
155           31, 7936,   47, 7808,   55, 7552,   59, 7040,   61, 6016,
156           62, 3968,   79, 7744,   87, 7488,   91, 6976,   93, 5952,
157           94, 3904,  103, 7360,  107, 6848,  109, 5824,  110, 3776,
158          115, 6592,  117, 5568,  118, 3520,  121, 5056,  122, 3008,
159          124, 1984,  143, 7712,  151, 7456,  155, 6944,  157, 5920,
160          158, 3872,  167, 7328,  171, 6816,  173, 5792,  174, 3744,
161          179, 6560,  181, 5536,  182, 3488,  185, 5024,  186, 2976,
162          188, 1952,  199, 7264,  203, 6752,  205, 5728,  206, 3680,
163          211, 6496,  213, 5472,  214, 3424,  217, 4960,  218, 2912,
164          220, 1888,  227, 6368,  229, 5344,  230, 3296,  233, 4832,
165          234, 2784,  236, 1760,  241, 4576,  242, 2528,  244, 1504,
166          248,  992,  271, 7696,  279, 7440,  283, 6928,  285, 5904,
167          286, 3856,  295, 7312,  299, 6800,  301, 5776,  302, 3728,
168          307, 6544,  309, 5520,  310, 3472,  313, 5008,  314, 2960,
169          316, 1936,  327, 7248,  331, 6736,  333, 5712,  334, 3664,
170          339, 6480,  341, 5456,  342, 3408,  345, 4944,  346, 2896,
171          348, 1872,  355, 6352,  357, 5328,  358, 3280,  361, 4816,
172          362, 2768,  364, 1744,  369, 4560,  370, 2512,  372, 1488,
173          376,  976,  391, 7216,  395, 6704,  397, 5680,  398, 3632,
174          403, 6448,  405, 5424,  406, 3376,  409, 4912,  410, 2864,
175          412, 1840,  419, 6320,  421, 5296,  422, 3248,  425, 4784,
176          426, 2736,  428, 1712,  433, 4528,  434, 2480,  436, 1456,
177          440,  944,  451, 6256,  453, 5232,  454, 3184,  457, 4720,
178          458, 2672,  460, 1648,  465, 4464,  466, 2416,  468, 1392,
179          472,  880,  481, 4336,  482, 2288,  484, 1264,  488,  752,
180          527, 7688,  535, 7432,  539, 6920,  541, 5896,  542, 3848,
181          551, 7304,  555, 6792,  557, 5768,  558, 3720,  563, 6536,
182          565, 5512,  566, 3464,  569, 5000,  570, 2952,  572, 1928,
183          583, 7240,  587, 6728,  589, 5704,  590, 3656,  595, 6472,
184          597, 5448,  598, 3400,  601, 4936,  602, 2888,  604, 1864,
185          611, 6344,  613, 5320,  614, 3272,  617, 4808,  618, 2760,
186          620, 1736,  625, 4552,  626, 2504,  628, 1480,  632,  968,
187          647, 7208,  651, 6696,  653, 5672,  654, 3624,  659, 6440,
188          661, 5416,  662, 3368,  665, 4904,  666, 2856,  668, 1832,
189          675, 6312,  677, 5288,  678, 3240,  681, 4776,  682, 2728,
190          684, 1704,  689, 4520,  690, 2472,  692, 1448,  696,  936,
191          707, 6248,  709, 5224,  710, 3176,  713, 4712,  714, 2664,
192          716, 1640,  721, 4456,  722, 2408,  724, 1384,  728,  872,
193          737, 4328,  738, 2280,  740, 1256,  775, 7192,  779, 6680,
194          781, 5656,  782, 3608,  787, 6424,  789, 5400,  790, 3352,
195          793, 4888,  794, 2840,  796, 1816,  803, 6296,  805, 5272,
196          806, 3224,  809, 4760,  810, 2712,  812, 1688,  817, 4504,
197          818, 2456,  820, 1432,  824,  920,  835, 6232,  837, 5208,
198          838, 3160,  841, 4696,  842, 2648,  844, 1624,  849, 4440,
199          850, 2392,  852, 1368,  865, 4312,  866, 2264,  868, 1240,
200          899, 6200,  901, 5176,  902, 3128,  905, 4664,  906, 2616,
201          908, 1592,  913, 4408,  914, 2360,  916, 1336,  929, 4280,
202          930, 2232,  932, 1208,  961, 4216,  962, 2168,  964, 1144,
203         1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844,
204         1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532,
205         1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924,
206         1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468,
207         1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860,
208         1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756,
209         1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204,
210         1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412,
211         1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308,
212         1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700,
213         1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220,
214         1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452,
215         1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188,
216         1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396,
217         1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292,
218         1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684,
219         1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204,
220         1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436,
221         1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172,
222         1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404,
223         1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164,
224         1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412,
225         1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804,
226         1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700,
227         1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196,
228         1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380,
229         1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116,
230         1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268,
231         1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148,
232         1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332,
233         1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156,
234         1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890,
235         2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714,
236         2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946,
237         2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466,
238         2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338,
239         2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546,
240         2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618,
241         2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850,
242         2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722,
243         2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170,
244         2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322,
245         2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418,
246         2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290,
247         2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498,
248         2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690,
249         2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170,
250         2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274,
251         2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594,
252         2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826,
253         2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698,
254         2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682,
255         2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114,
256         2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170,
257         2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250,
258         2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638,
259         3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870,
260         3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486,
261         3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294,
262         3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262,
263         3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374,
264         3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134,
265         3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142,
266         3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889,
267         4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505,
268         4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465,
269         4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801,
270         4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433,
271         4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769,
272         4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449,
273         4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393,
274         4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497,
275         4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169,
276         4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409,
277         4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745,
278         4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169,
279         4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405,
280         5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181,
281         5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403,
282         6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386,
283         2274, 1612, 1364, 1252,  856,  744,  496,
284         /* Table II 2 of 13. */
285            3, 6144,    5, 5120,    6, 3072,    9, 4608,   10, 2560,
286           12, 1536,   17, 4352,   18, 2304,   20, 1280,   24,  768,
287           33, 4224,   34, 2176,   36, 1152,   40,  640,   48,  384,
288           65, 4160,   66, 2112,   68, 1088,   72,  576,   80,  320,
289           96,  192,  129, 4128,  130, 2080,  132, 1056,  136,  544,
290          144,  288,  257, 4112,  258, 2064,  260, 1040,  264,  528,
291          513, 4104,  514, 2056,  516, 1032, 1025, 4100, 1026, 2052,
292         2049, 4098, 4097, 2050, 1028,  520,  272,  160
293 };
294
295
296 /*===========================================*/
297 /* Local function prototypes                 */
298 /*===========================================*/
299 static gboolean     onecode_is_data_valid (const gchar      *data);
300
301 static gchar       *onecode_encode        (const gchar      *data);
302
303 static lglBarcode  *onecode_vectorize     (const gchar      *code);
304
305 static void         int104_mult_uint      (Int104           *x,
306                                            guint             y);
307 static void         int104_add_uint       (Int104           *x,
308                                            guint             y);
309 static void         int104_add_uint64     (Int104           *x,
310                                            guint64           y);
311 static guint        int104_div_uint       (Int104           *x,
312                                            guint             y);
313 #ifdef DEBUG
314 static void         int104_print          (Int104           *x);
315 #endif
316
317 static unsigned short   USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr );
318
319
320 /****************************************************************************/
321 /* Generate new One Code barcode structure from data.                       */
322 /****************************************************************************/
323 lglBarcode *
324 lgl_barcode_onecode_new (lglBarcodeType  type,
325                          gboolean        text_flag,
326                          gboolean        checksum_flag,
327                          gdouble         w,
328                          gdouble         h,
329                          const gchar    *data)
330 {
331         gchar              *code;
332         lglBarcode         *bc;
333
334         if ( type != LGL_BARCODE_TYPE_ONECODE )
335         {
336                 g_message ("Invalid barcode type for ONECODE backend.");
337                 return NULL;
338         }
339
340
341         /* Validate data */
342         if ( !onecode_is_data_valid (data) )
343         {
344                 return NULL;
345         }
346
347         /* Now get code string */
348         code = onecode_encode (data);
349         if (code == NULL) {
350                 return NULL;
351         }
352
353         /* Now vectorize encoded data. */
354         bc = onecode_vectorize (code);
355
356         g_free (code);
357
358         return bc;
359 }
360
361
362 /*--------------------------------------------------------------------------*/
363 /* Validate if string is of proper length & contains only valid characters. */
364 /*--------------------------------------------------------------------------*/
365 static gboolean
366 onecode_is_data_valid (const gchar *data)
367 {
368         gchar *p;
369         gint   str_length;
370
371         if (!data)
372         {
373                 return FALSE;
374         }
375
376         str_length = strlen (data);
377         if ( (str_length != 20) &&
378              (str_length != 25) &&
379              (str_length != 29) &&
380              (str_length != 31) )
381         {
382                 return FALSE;
383         }
384
385         for ( p = (gchar *)data; *p != 0; p++ )
386         {
387                 if (!g_ascii_isdigit (*p))
388                 {
389                         return FALSE;
390                 }
391         }
392
393         if (data[1] > '4')
394         {
395                 return FALSE; /* Invalid Barcode Identifier. */
396         }
397
398         return TRUE;
399 }
400
401
402 /*--------------------------------------------------------------------------*/
403 /* PRIVATE.  Generate string of symbols, representing barcode.              */
404 /*--------------------------------------------------------------------------*/
405 static gchar *
406 onecode_encode (const gchar *data)
407 {
408         Int104   value = {{0}};
409         gint     i;
410         guint    crc11;
411         guint    codeword[10];
412         guint    character[10];
413         gint     d, a;
414         GString *code;
415
416         /*-----------------------------------------------------------*/
417         /* Step 1 -- Conversion of Data Fields into Binary Data      */
418         /*-----------------------------------------------------------*/
419
420         /* Step 1.a -- Routing Code */
421         for ( i = 20; data[i] != 0; i++ )
422         {
423                 int104_mult_uint (&value, 10);
424                 int104_add_uint  (&value, data[i] - '0');
425         }
426         switch ( i-20 )
427         {
428         case 0:
429                 break;
430         case 5:
431                 int104_add_uint  (&value, 1);
432                 break;
433         case 9:
434                 int104_add_uint  (&value, 1);
435                 int104_add_uint  (&value, 100000);
436                 break;
437         case 11:
438                 int104_add_uint   (&value, 1);
439                 int104_add_uint   (&value, 100000);
440                 int104_add_uint64 (&value, 1000000000);
441                 break;
442         default:
443                 return NULL; /* Should not happen if length tests passed. */
444                 break;
445         }
446
447         /* Step 1.b -- Tracking Code */
448         int104_mult_uint (&value, 10);
449         int104_add_uint  (&value, data[0] - '0');
450         int104_mult_uint (&value, 5);
451         int104_add_uint  (&value, data[1] - '0');
452
453         for ( i = 2; i < 20; i++ )
454         {
455                 int104_mult_uint (&value, 10);
456                 int104_add_uint  (&value, data[i] - '0');
457         }
458
459
460         /*-----------------------------------------------------------*/
461         /* Step 2 -- Generation of 11-Bit CRC on Binary Data         */
462         /*-----------------------------------------------------------*/
463
464         crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.byte );
465
466
467         /*-----------------------------------------------------------*/
468         /* Step 3 -- Conversion of Binary Data to Codewords          */
469         /*-----------------------------------------------------------*/
470
471         codeword[9] = int104_div_uint (&value, 636);
472         for ( i = 8; i >= 1; i-- )
473         {
474                 codeword[i] = int104_div_uint (&value, 1365);
475         }
476         codeword[0] = int104_div_uint (&value, 659);
477
478
479         /*-----------------------------------------------------------*/
480         /* Step 4 -- Inserting Additional Information into Codewords */
481         /*-----------------------------------------------------------*/
482
483         codeword[9] *= 2;
484         codeword[0] += (crc11 & 0x400) ? 659 : 0;
485
486
487         /*-----------------------------------------------------------*/
488         /* Step 5 -- Conversion from Codewords to Characters         */
489         /*-----------------------------------------------------------*/
490
491         for ( i = 0; i < 10; i++ )
492         {
493                 character[i] = character_table[ codeword[i] ];
494
495                 if ( crc11 & (1<<i) )
496                 {
497                         character[i] = ~character[i] & 0x1FFF;
498                 }
499         }
500
501
502         /*-----------------------------------------------------------*/
503         /* Step 6 -- Conversion from Characters to IMail Barcode     */
504         /*-----------------------------------------------------------*/
505
506         code = g_string_new ("");
507         for ( i = 0; i < 65; i++ )
508         {
509                 d = (character[ bar_map[i].descender.i ] & bar_map[i].descender.mask) != 0;
510                 a = (character[ bar_map[i].ascender.i ]  & bar_map[i].ascender.mask)  != 0;
511
512                 code = g_string_append (code, tdaf_table[ (a<<1) + d ]);
513         }
514
515
516         return g_string_free (code, FALSE);
517 }
518
519
520 /*--------------------------------------------------------------------------*/
521 /* Vectorize encoded data.                                                  */
522 /*--------------------------------------------------------------------------*/
523 static lglBarcode *
524 onecode_vectorize (const gchar  *code)
525 {
526         lglBarcode         *bc;
527         gchar              *p;
528         gdouble             x, y, length, width;
529
530         bc = lgl_barcode_new ();
531
532         /* Now traverse the code string and create a list of lines */
533         x = ONECODE_HORIZ_MARGIN;
534         for (p = (gchar *)code; *p != 0; p++)
535         {
536                 y = ONECODE_VERT_MARGIN;
537                 switch ( *p )
538                 {
539                 case 'T':
540                         y      += ONECODE_TRACKER_OFFSET;
541                         length  = ONECODE_TRACKER_HEIGHT;
542                         break;
543                 case 'D':
544                         y      += ONECODE_DESCENDER_OFFSET;
545                         length  = ONECODE_DESCENDER_HEIGHT;
546                         break;
547                 case 'A':
548                         y      += ONECODE_ASCENDER_OFFSET;
549                         length  = ONECODE_ASCENDER_HEIGHT;
550                         break;
551                 case 'F':
552                         y      += ONECODE_FULL_OFFSET;
553                         length  = ONECODE_FULL_HEIGHT;
554                         break;
555                 default:
556                         break;
557                 }
558                 width = ONECODE_BAR_WIDTH;
559
560                 lgl_barcode_add_box (bc, x, y, width, length);
561
562                 x += ONECODE_BAR_PITCH;
563         }
564
565         bc->width = x + ONECODE_HORIZ_MARGIN;
566         bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
567
568         return bc;
569 }
570
571
572 /*--------------------------------------------------------------------------*/
573 /* Multiply 104 bit integer by unsigned int.                                */
574 /*--------------------------------------------------------------------------*/
575 static void
576 int104_mult_uint (Int104  *x,
577                   guint    y)
578 {
579         gint    i;
580         guint64 temp, carry;
581
582         carry = 0;
583         for ( i = 12; i >= 0; i-- )
584         {
585                 temp = x->byte[i] * y  +  carry;
586
587                 x->byte[i] = temp & 0xFF;
588                 carry      = temp >> 8;
589         }
590 }
591
592
593 /*--------------------------------------------------------------------------*/
594 /* Add unsigned int to 104 bit integer.                                     */
595 /*--------------------------------------------------------------------------*/
596 static void
597 int104_add_uint (Int104  *x,
598                  guint     y)
599 {
600         gint    i;
601         guint   temp, carry;
602
603         carry = 0;
604         for ( i = 12; i >= 0; i-- )
605         {
606                 temp = x->byte[i] + (y & 0xFF) + carry;
607
608                 x->byte[i]  = temp & 0xFF;
609                 carry       = temp >> 8;
610                 y           = y >> 8;
611         }
612 }
613
614
615 /*--------------------------------------------------------------------------*/
616 /* Add unsigned 64 bit integer to 104 bit integer.                          */
617 /*--------------------------------------------------------------------------*/
618 static void
619 int104_add_uint64 (Int104  *x,
620                    guint64   y)
621 {
622         gint    i;
623         guint64 temp, carry;
624
625         carry = 0;
626         for ( i = 12; i >= 0; i-- )
627         {
628                 temp = x->byte[i] + (y & 0xFF) + carry;
629
630                 x->byte[i]  = temp & 0xFF;
631                 carry       = temp >> 8;
632                 y           = y >> 8;
633         }
634 }
635
636
637 /*--------------------------------------------------------------------------*/
638 /* Divide 104 bit integer by unsigned int.                                  */
639 /*--------------------------------------------------------------------------*/
640 static guint
641 int104_div_uint (Int104 *x,
642                  guint   y)
643 {
644         guint carry, tmp, i;
645
646         carry = 0;
647         for ( i = 0; i < 13; i++ )
648         {
649                 tmp        = x->byte[i] + (carry<<8);
650                 x->byte[i] = tmp / y;
651                 carry      = tmp % y;
652         }
653
654         return carry;
655 }
656
657
658 /*--------------------------------------------------------------------------*/
659 /* Print hex representation of 104 bit integer.  (For debugging)            */
660 /*--------------------------------------------------------------------------*/
661 #ifdef DEBUG
662 static void
663 int104_print (Int104  *x)
664 {
665         gint i;
666
667         for ( i = 0; i < 13; i++ )
668         {
669                 g_print ("%02x ", x->byte[i] & 0xFF);
670         }
671         g_print ("\n");
672 }
673 #endif
674
675
676 /***************************************************************************
677  ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence
678  **
679  ** Inputs:
680  **   ByteAttayPtr is the address of a 13 byte array holding 102 bytes which
681  **   are right justified - ie: the leftmost 2 bits of the first byte do not
682  **   hold data and must be set to zero.
683  **
684  ** Outputs:
685  **   return unsigned short - 11 bit Frame Check Sequence (right justified)
686  **
687  ** From Appendix C of USPS publication USPS-B-3200E, 07/08/05.
688  ***************************************************************************/
689 unsigned short
690 USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr )
691 {
692         unsigned short  GeneratorPolynomial = 0x0F35;
693         unsigned short  FrameCheckSequence  = 0x07FF;
694         unsigned short  Data;
695         int             ByteIndex, Bit;
696
697         /* Do most significant byte skipping the 2 most significant bits */
698         Data = *ByteArrayPtr << 5;
699         ByteArrayPtr++;
700         for ( Bit = 2; Bit < 8; Bit++ )
701         {
702                 if ( (FrameCheckSequence ^ Data) & 0x400 )
703                 {
704                         FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
705                 }
706                 else
707                 {
708                         FrameCheckSequence = (FrameCheckSequence << 1);
709                 }
710                 FrameCheckSequence &= 0x7FF;
711                 Data <<= 1;
712         }
713
714         /* Do rest of the bytes */
715         for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ )
716         {
717                 Data = *ByteArrayPtr << 3;
718                 ByteArrayPtr++;
719                 for ( Bit = 0; Bit < 8; Bit++ )
720                 {
721                         if ( (FrameCheckSequence ^ Data) & 0x0400 )
722                         {
723                                 FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
724                         }
725                         else
726                         {
727                                 FrameCheckSequence = (FrameCheckSequence << 1);
728                         }
729                         FrameCheckSequence &= 0x7FF;
730                         Data <<= 1;
731                 }
732         }
733
734         return FrameCheckSequence;
735 }
736
737
738
739
740 /*
741  * Local Variables:       -- emacs
742  * mode: C                -- emacs
743  * c-basic-offset: 8      -- emacs
744  * tab-width: 8           -- emacs
745  * indent-tabs-mode: nil  -- emacs
746  * End:                   -- emacs
747  */