]> git.sur5r.net Git - glabels/blob - libglbarcode/lgl-barcode-onecode.c
Fixed potential memory leak.
[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
298 /*===========================================*/
299 /* Local function prototypes                 */
300 /*===========================================*/
301 static gboolean     is_string_valid    (const gchar      *data);
302
303 static gchar       *onecode_encode     (const gchar      *data);
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 static lglBarcode  *onecode_vectorize  (const gchar      *code);
320
321
322 /****************************************************************************/
323 /* Generate list of lines that form the barcode for the given digits.       */
324 /****************************************************************************/
325 lglBarcode *
326 lgl_barcode_onecode_new (lglBarcodeType  type,
327                          gboolean        text_flag,
328                          gboolean        checksum_flag,
329                          gdouble         w,
330                          gdouble         h,
331                          const gchar    *data)
332 {
333         gchar              *code;
334         lglBarcode         *bc;
335
336         if ( type != LGL_BARCODE_TYPE_ONECODE )
337         {
338                 g_message ("Invalid barcode type for ONECODE backend.");
339                 return NULL;
340         }
341
342         /* First get code string */
343         code = onecode_encode (data);
344         if (code == NULL) {
345                 return NULL;
346         }
347
348         /* Now vectorize encoded data. */
349         bc = onecode_vectorize (code);
350
351         g_free (code);
352
353         return bc;
354 }
355
356
357 /*--------------------------------------------------------------------------*/
358 /* PRIVATE.  Generate string of symbols, representing barcode.              */
359 /*--------------------------------------------------------------------------*/
360 static gchar *
361 onecode_encode (const gchar *data)
362 {
363         Int104   value = {{0}};
364         gint     i;
365         guint    crc11;
366         guint    codeword[10];
367         guint    character[10];
368         gint     d, a;
369         GString *code;
370
371         if ( !is_string_valid (data) )
372         {
373                 return NULL;
374         }
375
376
377         /*-----------------------------------------------------------*/
378         /* Step 1 -- Conversion of Data Fields into Binary Data      */
379         /*-----------------------------------------------------------*/
380
381         /* Step 1.a -- Routing Code */
382         for ( i = 20; data[i] != 0; i++ )
383         {
384                 int104_mult_uint (&value, 10);
385                 int104_add_uint  (&value, data[i] - '0');
386         }
387         switch ( i-20 )
388         {
389         case 0:
390                 break;
391         case 5:
392                 int104_add_uint  (&value, 1);
393                 break;
394         case 9:
395                 int104_add_uint  (&value, 1);
396                 int104_add_uint  (&value, 100000);
397                 break;
398         case 11:
399                 int104_add_uint   (&value, 1);
400                 int104_add_uint   (&value, 100000);
401                 int104_add_uint64 (&value, 1000000000);
402                 break;
403         default:
404                 return NULL; /* Should not happen if length tests passed. */
405                 break;
406         }
407
408         /* Step 1.b -- Tracking Code */
409         int104_mult_uint (&value, 10);
410         int104_add_uint  (&value, data[0] - '0');
411         int104_mult_uint (&value, 5);
412         int104_add_uint  (&value, data[1] - '0');
413
414         for ( i = 2; i < 20; i++ )
415         {
416                 int104_mult_uint (&value, 10);
417                 int104_add_uint  (&value, data[i] - '0');
418         }
419
420
421         /*-----------------------------------------------------------*/
422         /* Step 2 -- Generation of 11-Bit CRC on Binary Data         */
423         /*-----------------------------------------------------------*/
424
425         crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.byte );
426
427
428         /*-----------------------------------------------------------*/
429         /* Step 3 -- Conversion of Binary Data to Codewords          */
430         /*-----------------------------------------------------------*/
431
432         codeword[9] = int104_div_uint (&value, 636);
433         for ( i = 8; i >= 1; i-- )
434         {
435                 codeword[i] = int104_div_uint (&value, 1365);
436         }
437         codeword[0] = int104_div_uint (&value, 659);
438
439
440         /*-----------------------------------------------------------*/
441         /* Step 4 -- Inserting Additional Information into Codewords */
442         /*-----------------------------------------------------------*/
443
444         codeword[9] *= 2;
445         codeword[0] += (crc11 & 0x400) ? 659 : 0;
446
447
448         /*-----------------------------------------------------------*/
449         /* Step 5 -- Conversion from Codewords to Characters         */
450         /*-----------------------------------------------------------*/
451
452         for ( i = 0; i < 10; i++ )
453         {
454                 character[i] = character_table[ codeword[i] ];
455
456                 if ( crc11 & (1<<i) )
457                 {
458                         character[i] = ~character[i] & 0x1FFF;
459                 }
460         }
461
462
463         /*-----------------------------------------------------------*/
464         /* Step 6 -- Conversion from Characters to IMail Barcode     */
465         /*-----------------------------------------------------------*/
466
467         code = g_string_new ("");
468         for ( i = 0; i < 65; i++ )
469         {
470                 d = (character[ bar_map[i].descender.i ] & bar_map[i].descender.mask) != 0;
471                 a = (character[ bar_map[i].ascender.i ]  & bar_map[i].ascender.mask)  != 0;
472
473                 code = g_string_append (code, tdaf_table[ (a<<1) + d ]);
474         }
475
476
477         return g_string_free (code, FALSE);
478 }
479
480
481 /*--------------------------------------------------------------------------*/
482 /* Validate if string is of proper length & contains only valid characters. */
483 /*--------------------------------------------------------------------------*/
484 static gboolean
485 is_string_valid (const gchar *data)
486 {
487         gchar *p;
488         gint   str_length;
489
490         if (!data) {
491                 return FALSE;
492         }
493
494         str_length = strlen (data);
495         if ( (str_length != 20) &&
496              (str_length != 25) &&
497              (str_length != 29) &&
498              (str_length != 31) )
499         {
500                 return FALSE;
501         }
502
503         for ( p = (gchar *)data; *p != 0; p++ )
504         {
505                 if (!g_ascii_isdigit (*p))
506                 {
507                         return FALSE;
508                 }
509         }
510
511         if (data[1] > '4')
512         {
513                 return FALSE; /* Invalid Barcode Identifier. */
514         }
515
516         return TRUE;
517 }
518
519
520 /*--------------------------------------------------------------------------*/
521 /* Multiply 104 bit integer by unsigned int.                                */
522 /*--------------------------------------------------------------------------*/
523 static void
524 int104_mult_uint (Int104  *x,
525                   guint    y)
526 {
527         gint    i;
528         guint64 temp, carry;
529
530         carry = 0;
531         for ( i = 12; i >= 0; i-- )
532         {
533                 temp = x->byte[i] * y  +  carry;
534
535                 x->byte[i] = temp & 0xFF;
536                 carry      = temp >> 8;
537         }
538 }
539
540
541 /*--------------------------------------------------------------------------*/
542 /* Add unsigned int to 104 bit integer.                                     */
543 /*--------------------------------------------------------------------------*/
544 static void
545 int104_add_uint (Int104  *x,
546                  guint     y)
547 {
548         gint    i;
549         guint   temp, carry;
550
551         carry = 0;
552         for ( i = 12; i >= 0; i-- )
553         {
554                 temp = x->byte[i] + (y & 0xFF) + carry;
555
556                 x->byte[i]  = temp & 0xFF;
557                 carry       = temp >> 8;
558                 y           = y >> 8;
559         }
560 }
561
562
563 /*--------------------------------------------------------------------------*/
564 /* Add unsigned 64 bit integer to 104 bit integer.                          */
565 /*--------------------------------------------------------------------------*/
566 static void
567 int104_add_uint64 (Int104  *x,
568                    guint64   y)
569 {
570         gint    i;
571         guint64 temp, carry;
572
573         carry = 0;
574         for ( i = 12; i >= 0; i-- )
575         {
576                 temp = x->byte[i] + (y & 0xFF) + carry;
577
578                 x->byte[i]  = temp & 0xFF;
579                 carry       = temp >> 8;
580                 y           = y >> 8;
581         }
582 }
583
584
585 /*--------------------------------------------------------------------------*/
586 /* Divide 104 bit integer by unsigned int.                                  */
587 /*--------------------------------------------------------------------------*/
588 static guint
589 int104_div_uint (Int104 *x,
590                  guint   y)
591 {
592         guint carry, tmp, i;
593
594         carry = 0;
595         for ( i = 0; i < 13; i++ )
596         {
597                 tmp        = x->byte[i] + (carry<<8);
598                 x->byte[i] = tmp / y;
599                 carry      = tmp % y;
600         }
601
602         return carry;
603 }
604
605
606 /*--------------------------------------------------------------------------*/
607 /* Print hex representation of 104 bit integer.  (For debugging)            */
608 /*--------------------------------------------------------------------------*/
609 #ifdef DEBUG
610 static void
611 int104_print (Int104  *x)
612 {
613         gint i;
614
615         for ( i = 0; i < 13; i++ )
616         {
617                 g_print ("%02x ", x->byte[i] & 0xFF);
618         }
619         g_print ("\n");
620 }
621 #endif
622
623
624 /***************************************************************************
625  ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence
626  **
627  ** Inputs:
628  **   ByteAttayPtr is the address of a 13 byte array holding 102 bytes which
629  **   are right justified - ie: the leftmost 2 bits of the first byte do not
630  **   hold data and must be set to zero.
631  **
632  ** Outputs:
633  **   return unsigned short - 11 bit Frame Check Sequence (right justified)
634  **
635  ** From Appendix C of USPS publication USPS-B-3200E, 07/08/05.
636  ***************************************************************************/
637 unsigned short
638 USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr )
639 {
640         unsigned short  GeneratorPolynomial = 0x0F35;
641         unsigned short  FrameCheckSequence  = 0x07FF;
642         unsigned short  Data;
643         int             ByteIndex, Bit;
644
645         /* Do most significant byte skipping the 2 most significant bits */
646         Data = *ByteArrayPtr << 5;
647         ByteArrayPtr++;
648         for ( Bit = 2; Bit < 8; Bit++ )
649         {
650                 if ( (FrameCheckSequence ^ Data) & 0x400 )
651                 {
652                         FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
653                 }
654                 else
655                 {
656                         FrameCheckSequence = (FrameCheckSequence << 1);
657                 }
658                 FrameCheckSequence &= 0x7FF;
659                 Data <<= 1;
660         }
661
662         /* Do rest of the bytes */
663         for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ )
664         {
665                 Data = *ByteArrayPtr << 3;
666                 ByteArrayPtr++;
667                 for ( Bit = 0; Bit < 8; Bit++ )
668                 {
669                         if ( (FrameCheckSequence ^ Data) & 0x0400 )
670                         {
671                                 FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
672                         }
673                         else
674                         {
675                                 FrameCheckSequence = (FrameCheckSequence << 1);
676                         }
677                         FrameCheckSequence &= 0x7FF;
678                         Data <<= 1;
679                 }
680         }
681
682         return FrameCheckSequence;
683 }
684
685
686 /*--------------------------------------------------------------------------*/
687 /* Vectorize encoded data.                                                  */
688 /*--------------------------------------------------------------------------*/
689 static lglBarcode *
690 onecode_vectorize (const gchar  *code)
691 {
692         lglBarcode         *bc;
693         gchar              *p;
694         gdouble             x, y, length, width;
695
696         bc = lgl_barcode_new ();
697
698         /* Now traverse the code string and create a list of lines */
699         x = ONECODE_HORIZ_MARGIN;
700         for (p = (gchar *)code; *p != 0; p++)
701         {
702                 y = ONECODE_VERT_MARGIN;
703                 switch ( *p )
704                 {
705                 case 'T':
706                         y      += ONECODE_TRACKER_OFFSET;
707                         length  = ONECODE_TRACKER_HEIGHT;
708                         break;
709                 case 'D':
710                         y      += ONECODE_DESCENDER_OFFSET;
711                         length  = ONECODE_DESCENDER_HEIGHT;
712                         break;
713                 case 'A':
714                         y      += ONECODE_ASCENDER_OFFSET;
715                         length  = ONECODE_ASCENDER_HEIGHT;
716                         break;
717                 case 'F':
718                         y      += ONECODE_FULL_OFFSET;
719                         length  = ONECODE_FULL_HEIGHT;
720                         break;
721                 default:
722                         break;
723                 }
724                 width = ONECODE_BAR_WIDTH;
725
726                 lgl_barcode_add_box (bc, x, y, width, length);
727
728                 x += ONECODE_BAR_PITCH;
729         }
730
731         bc->width = x + ONECODE_HORIZ_MARGIN;
732         bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
733
734         return bc;
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  */