From b071ef81f3bb86f042a317dd509b10f2f52aaefb Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Fri, 22 Oct 2010 23:38:11 -0400 Subject: [PATCH] Added native OneCode barcode backend. --- src/Makefile.am | 4 + src/bc-backends.c | 4 + src/bc-onecode.c | 725 ++++++++++++++++++++++++++++++++++++++++++++++ src/bc-onecode.h | 48 +++ 4 files changed, 781 insertions(+) create mode 100644 src/bc-onecode.c create mode 100644 src/bc-onecode.h diff --git a/src/Makefile.am b/src/Makefile.am index aac2b7ef..77f42090 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -123,6 +123,8 @@ glabels_3_SOURCES = \ bc-gnubarcode.h \ bc-zint.c \ bc-zint.h \ + bc-onecode.c \ + bc-onecode.h \ bc-postnet.c \ bc-postnet.h \ bc-iec16022.c \ @@ -252,6 +254,8 @@ glabels_3_batch_SOURCES = \ bc-gnubarcode.h \ bc-zint.c \ bc-zint.h \ + bc-onecode.c \ + bc-onecode.h \ bc-postnet.c \ bc-postnet.h \ bc-iec16022.c \ diff --git a/src/bc-backends.c b/src/bc-backends.c index 3d966034..3f69684c 100644 --- a/src/bc-backends.c +++ b/src/bc-backends.c @@ -26,6 +26,7 @@ #include #include "bc-postnet.h" +#include "bc-onecode.h" #include "bc-gnubarcode.h" #include "bc-zint.h" #include "bc-iec16022.h" @@ -113,6 +114,9 @@ static const Style styles[] = { { "built-in", "CEPNET", N_("CEPNET"), gl_barcode_postnet_new, FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8}, + { "built-in", "ONECODE", N_("One Code"), gl_barcode_onecode_new, + FALSE, FALSE, TRUE, FALSE, "12345678901234567890", FALSE, 20}, + #ifdef HAVE_LIBBARCODE { "gnu-barcode", "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new, diff --git a/src/bc-onecode.c b/src/bc-onecode.c new file mode 100644 index 00000000..d62460a8 --- /dev/null +++ b/src/bc-onecode.c @@ -0,0 +1,725 @@ +/* + * bc-onecode.c + * Copyright (C) 2010 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gLabels is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gLabels. If not, see . + */ + +/* + * This module implements the Intelligent Mail (OneCode) barcode + * specified in the USPS specification USPS-B-3200E, 07/08/05. + */ + +#include + +#include "bc-onecode.h" + +#include +#include +#include + +#include "debug.h" + + +/*========================================================*/ +/* Private macros and constants. */ +/*========================================================*/ + +#define CHAR_A 0 +#define CHAR_B 1 +#define CHAR_C 2 +#define CHAR_D 3 +#define CHAR_E 4 +#define CHAR_F 5 +#define CHAR_G 6 +#define CHAR_H 7 +#define CHAR_I 8 +#define CHAR_J 9 + +#define PTS_PER_INCH 72.0 + +#define ONECODE_BAR_WIDTH ( 0.02 * PTS_PER_INCH ) +#define ONECODE_FULL_HEIGHT ( 0.145 * PTS_PER_INCH ) +#define ONECODE_ASCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) +#define ONECODE_DESCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) +#define ONECODE_TRACKER_HEIGHT ( 0.048 * PTS_PER_INCH ) +#define ONECODE_FULL_OFFSET 0 +#define ONECODE_ASCENDER_OFFSET 0 +#define ONECODE_DESCENDER_OFFSET ( 0.0485 * PTS_PER_INCH ) +#define ONECODE_TRACKER_OFFSET ( 0.0485 * PTS_PER_INCH ) +#define ONECODE_BAR_PITCH ( 0.0458 * PTS_PER_INCH ) +#define ONECODE_HORIZ_MARGIN ( 0.125 * PTS_PER_INCH ) +#define ONECODE_VERT_MARGIN ( 0.028 * PTS_PER_INCH ) + + +/*========================================================*/ +/* Private types. */ +/*========================================================*/ + +typedef struct { + guchar byte[13]; +} Int104; + +typedef struct { + struct { gint i; gint mask; } descender; + struct { gint i; gint mask; } ascender; +} BarMapEntry; + + +/*===========================================*/ +/* Private globals */ +/*===========================================*/ + +static BarMapEntry bar_map[] = { + /* 1 */ { { CHAR_H, 1<<2 }, { CHAR_E, 1<<3 } }, + /* 2 */ { { CHAR_B, 1<<10 }, { CHAR_A, 1<<0 } }, + /* 3 */ { { CHAR_J, 1<<12 }, { CHAR_C, 1<<8 } }, + /* 4 */ { { CHAR_F, 1<<5 }, { CHAR_G, 1<<11 } }, + /* 5 */ { { CHAR_I, 1<<9 }, { CHAR_D, 1<<1 } }, + /* 6 */ { { CHAR_A, 1<<1 }, { CHAR_F, 1<<12 } }, + /* 7 */ { { CHAR_C, 1<<5 }, { CHAR_B, 1<<8 } }, + /* 8 */ { { CHAR_E, 1<<4 }, { CHAR_J, 1<<11 } }, + /* 9 */ { { CHAR_G, 1<<3 }, { CHAR_I, 1<<10 } }, + /* 10 */ { { CHAR_D, 1<<9 }, { CHAR_H, 1<<6 } }, + /* 11 */ { { CHAR_F, 1<<11 }, { CHAR_B, 1<<4 } }, + /* 12 */ { { CHAR_I, 1<<5 }, { CHAR_C, 1<<12 } }, + /* 13 */ { { CHAR_J, 1<<10 }, { CHAR_A, 1<<2 } }, + /* 14 */ { { CHAR_H, 1<<1 }, { CHAR_G, 1<<7 } }, + /* 15 */ { { CHAR_D, 1<<6 }, { CHAR_E, 1<<9 } }, + /* 16 */ { { CHAR_A, 1<<3 }, { CHAR_I, 1<<6 } }, + /* 17 */ { { CHAR_G, 1<<4 }, { CHAR_C, 1<<7 } }, + /* 18 */ { { CHAR_B, 1<<1 }, { CHAR_J, 1<<9 } }, + /* 19 */ { { CHAR_H, 1<<10 }, { CHAR_F, 1<<2 } }, + /* 20 */ { { CHAR_E, 1<<0 }, { CHAR_D, 1<<8 } }, + /* 21 */ { { CHAR_G, 1<<2 }, { CHAR_A, 1<<4 } }, + /* 22 */ { { CHAR_I, 1<<11 }, { CHAR_B, 1<<0 } }, + /* 23 */ { { CHAR_J, 1<<8 }, { CHAR_D, 1<<12 } }, + /* 24 */ { { CHAR_C, 1<<6 }, { CHAR_H, 1<<7 } }, + /* 25 */ { { CHAR_F, 1<<1 }, { CHAR_E, 1<<10 } }, + /* 26 */ { { CHAR_B, 1<<12 }, { CHAR_G, 1<<9 } }, + /* 27 */ { { CHAR_H, 1<<3 }, { CHAR_I, 1<<0 } }, + /* 28 */ { { CHAR_F, 1<<8 }, { CHAR_J, 1<<7 } }, + /* 29 */ { { CHAR_E, 1<<6 }, { CHAR_C, 1<<10 } }, + /* 30 */ { { CHAR_D, 1<<4 }, { CHAR_A, 1<<5 } }, + /* 31 */ { { CHAR_I, 1<<4 }, { CHAR_F, 1<<7 } }, + /* 32 */ { { CHAR_H, 1<<11 }, { CHAR_B, 1<<9 } }, + /* 33 */ { { CHAR_G, 1<<0 }, { CHAR_J, 1<<6 } }, + /* 34 */ { { CHAR_A, 1<<6 }, { CHAR_E, 1<<8 } }, + /* 35 */ { { CHAR_C, 1<<1 }, { CHAR_D, 1<<2 } }, + /* 36 */ { { CHAR_F, 1<<9 }, { CHAR_I, 1<<12 } }, + /* 37 */ { { CHAR_E, 1<<11 }, { CHAR_G, 1<<1 } }, + /* 38 */ { { CHAR_J, 1<<5 }, { CHAR_H, 1<<4 } }, + /* 39 */ { { CHAR_D, 1<<3 }, { CHAR_B, 1<<2 } }, + /* 40 */ { { CHAR_A, 1<<7 }, { CHAR_C, 1<<0 } }, + /* 41 */ { { CHAR_B, 1<<3 }, { CHAR_E, 1<<1 } }, + /* 42 */ { { CHAR_G, 1<<10 }, { CHAR_D, 1<<5 } }, + /* 43 */ { { CHAR_I, 1<<7 }, { CHAR_J, 1<<4 } }, + /* 44 */ { { CHAR_C, 1<<11 }, { CHAR_F, 1<<6 } }, + /* 45 */ { { CHAR_A, 1<<8 }, { CHAR_H, 1<<12 } }, + /* 46 */ { { CHAR_E, 1<<2 }, { CHAR_I, 1<<1 } }, + /* 47 */ { { CHAR_F, 1<<10 }, { CHAR_D, 1<<0 } }, + /* 48 */ { { CHAR_J, 1<<3 }, { CHAR_A, 1<<9 } }, + /* 49 */ { { CHAR_G, 1<<5 }, { CHAR_C, 1<<4 } }, + /* 50 */ { { CHAR_H, 1<<8 }, { CHAR_B, 1<<7 } }, + /* 51 */ { { CHAR_F, 1<<0 }, { CHAR_E, 1<<5 } }, + /* 52 */ { { CHAR_C, 1<<3 }, { CHAR_A, 1<<10 } }, + /* 53 */ { { CHAR_G, 1<<12 }, { CHAR_J, 1<<2 } }, + /* 54 */ { { CHAR_D, 1<<11 }, { CHAR_B, 1<<6 } }, + /* 55 */ { { CHAR_I, 1<<8 }, { CHAR_H, 1<<9 } }, + /* 56 */ { { CHAR_F, 1<<4 }, { CHAR_A, 1<<11 } }, + /* 57 */ { { CHAR_B, 1<<5 }, { CHAR_C, 1<<2 } }, + /* 58 */ { { CHAR_J, 1<<1 }, { CHAR_E, 1<<12 } }, + /* 59 */ { { CHAR_I, 1<<3 }, { CHAR_G, 1<<6 } }, + /* 60 */ { { CHAR_H, 1<<0 }, { CHAR_D, 1<<7 } }, + /* 61 */ { { CHAR_E, 1<<7 }, { CHAR_H, 1<<5 } }, + /* 62 */ { { CHAR_A, 1<<12 }, { CHAR_B, 1<<11 } }, + /* 63 */ { { CHAR_C, 1<<9 }, { CHAR_J, 1<<0 } }, + /* 64 */ { { CHAR_G, 1<<8 }, { CHAR_F, 1<<3 } }, + /* 65 */ { { CHAR_D, 1<<10 }, { CHAR_I, 1<<2 } } +}; + +static gchar * tdaf_table[4] = { "T", "D", "A", "F" }; + +static guint character_table[] = { + /* Table I 5 of 13. */ + 31, 7936, 47, 7808, 55, 7552, 59, 7040, 61, 6016, + 62, 3968, 79, 7744, 87, 7488, 91, 6976, 93, 5952, + 94, 3904, 103, 7360, 107, 6848, 109, 5824, 110, 3776, + 115, 6592, 117, 5568, 118, 3520, 121, 5056, 122, 3008, + 124, 1984, 143, 7712, 151, 7456, 155, 6944, 157, 5920, + 158, 3872, 167, 7328, 171, 6816, 173, 5792, 174, 3744, + 179, 6560, 181, 5536, 182, 3488, 185, 5024, 186, 2976, + 188, 1952, 199, 7264, 203, 6752, 205, 5728, 206, 3680, + 211, 6496, 213, 5472, 214, 3424, 217, 4960, 218, 2912, + 220, 1888, 227, 6368, 229, 5344, 230, 3296, 233, 4832, + 234, 2784, 236, 1760, 241, 4576, 242, 2528, 244, 1504, + 248, 992, 271, 7696, 279, 7440, 283, 6928, 285, 5904, + 286, 3856, 295, 7312, 299, 6800, 301, 5776, 302, 3728, + 307, 6544, 309, 5520, 310, 3472, 313, 5008, 314, 2960, + 316, 1936, 327, 7248, 331, 6736, 333, 5712, 334, 3664, + 339, 6480, 341, 5456, 342, 3408, 345, 4944, 346, 2896, + 348, 1872, 355, 6352, 357, 5328, 358, 3280, 361, 4816, + 362, 2768, 364, 1744, 369, 4560, 370, 2512, 372, 1488, + 376, 976, 391, 7216, 395, 6704, 397, 5680, 398, 3632, + 403, 6448, 405, 5424, 406, 3376, 409, 4912, 410, 2864, + 412, 1840, 419, 6320, 421, 5296, 422, 3248, 425, 4784, + 426, 2736, 428, 1712, 433, 4528, 434, 2480, 436, 1456, + 440, 944, 451, 6256, 453, 5232, 454, 3184, 457, 4720, + 458, 2672, 460, 1648, 465, 4464, 466, 2416, 468, 1392, + 472, 880, 481, 4336, 482, 2288, 484, 1264, 488, 752, + 527, 7688, 535, 7432, 539, 6920, 541, 5896, 542, 3848, + 551, 7304, 555, 6792, 557, 5768, 558, 3720, 563, 6536, + 565, 5512, 566, 3464, 569, 5000, 570, 2952, 572, 1928, + 583, 7240, 587, 6728, 589, 5704, 590, 3656, 595, 6472, + 597, 5448, 598, 3400, 601, 4936, 602, 2888, 604, 1864, + 611, 6344, 613, 5320, 614, 3272, 617, 4808, 618, 2760, + 620, 1736, 625, 4552, 626, 2504, 628, 1480, 632, 968, + 647, 7208, 651, 6696, 653, 5672, 654, 3624, 659, 6440, + 661, 5416, 662, 3368, 665, 4904, 666, 2856, 668, 1832, + 675, 6312, 677, 5288, 678, 3240, 681, 4776, 682, 2728, + 684, 1704, 689, 4520, 690, 2472, 692, 1448, 696, 936, + 707, 6248, 709, 5224, 710, 3176, 713, 4712, 714, 2664, + 716, 1640, 721, 4456, 722, 2408, 724, 1384, 728, 872, + 737, 4328, 738, 2280, 740, 1256, 775, 7192, 779, 6680, + 781, 5656, 782, 3608, 787, 6424, 789, 5400, 790, 3352, + 793, 4888, 794, 2840, 796, 1816, 803, 6296, 805, 5272, + 806, 3224, 809, 4760, 810, 2712, 812, 1688, 817, 4504, + 818, 2456, 820, 1432, 824, 920, 835, 6232, 837, 5208, + 838, 3160, 841, 4696, 842, 2648, 844, 1624, 849, 4440, + 850, 2392, 852, 1368, 865, 4312, 866, 2264, 868, 1240, + 899, 6200, 901, 5176, 902, 3128, 905, 4664, 906, 2616, + 908, 1592, 913, 4408, 914, 2360, 916, 1336, 929, 4280, + 930, 2232, 932, 1208, 961, 4216, 962, 2168, 964, 1144, + 1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844, + 1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532, + 1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924, + 1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468, + 1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860, + 1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756, + 1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204, + 1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412, + 1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308, + 1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700, + 1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220, + 1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452, + 1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188, + 1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396, + 1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292, + 1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684, + 1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204, + 1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436, + 1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172, + 1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404, + 1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164, + 1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412, + 1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804, + 1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700, + 1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196, + 1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380, + 1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116, + 1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268, + 1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148, + 1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332, + 1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156, + 1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890, + 2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714, + 2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946, + 2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466, + 2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338, + 2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546, + 2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618, + 2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850, + 2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722, + 2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170, + 2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322, + 2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418, + 2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290, + 2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498, + 2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690, + 2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170, + 2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274, + 2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594, + 2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826, + 2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698, + 2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682, + 2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114, + 2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170, + 2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250, + 2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638, + 3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870, + 3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486, + 3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294, + 3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262, + 3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374, + 3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134, + 3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142, + 3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889, + 4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505, + 4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465, + 4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801, + 4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433, + 4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769, + 4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449, + 4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393, + 4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497, + 4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169, + 4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409, + 4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745, + 4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169, + 4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405, + 5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181, + 5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403, + 6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386, + 2274, 1612, 1364, 1252, 856, 744, 496, + /* Table II 2 of 13. */ + 3, 6144, 5, 5120, 6, 3072, 9, 4608, 10, 2560, + 12, 1536, 17, 4352, 18, 2304, 20, 1280, 24, 768, + 33, 4224, 34, 2176, 36, 1152, 40, 640, 48, 384, + 65, 4160, 66, 2112, 68, 1088, 72, 576, 80, 320, + 96, 192, 129, 4128, 130, 2080, 132, 1056, 136, 544, + 144, 288, 257, 4112, 258, 2064, 260, 1040, 264, 528, + 513, 4104, 514, 2056, 516, 1032, 1025, 4100, 1026, 2052, + 2049, 4098, 4097, 2050, 1028, 520, 272, 160 +}; + + + + +/*===========================================*/ +/* Local function prototypes */ +/*===========================================*/ +static gboolean is_string_valid (const gchar *digits); + +static gchar *onecode_code (const gchar *digits); + +static void int104_mult_uint (Int104 *x, + guint y); +static void int104_add_uint (Int104 *x, + guint y); +static void int104_add_uint64 (Int104 *x, + guint64 y); +static guint int104_div_uint (Int104 *x, + guint y); +static void int104_print (Int104 *x); + +unsigned short USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr ); + + +/****************************************************************************/ +/* Generate list of lines that form the barcode for the given digits. */ +/****************************************************************************/ +glBarcode * +gl_barcode_onecode_new (const gchar *id, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *digits) +{ + gchar *code, *p; + glBarcode *gbc; + gdouble x, y, length, width; + + /* First get code string */ + code = onecode_code (digits); + if (code == NULL) { + return NULL; + } + + gbc = gl_barcode_new (); + + /* Now traverse the code string and create a list of lines */ + x = ONECODE_HORIZ_MARGIN; + for (p = code; *p != 0; p++) { + y = ONECODE_VERT_MARGIN; + switch ( *p ) + { + case 'T': + y += ONECODE_TRACKER_OFFSET; + length = ONECODE_TRACKER_HEIGHT; + break; + case 'D': + y += ONECODE_DESCENDER_OFFSET; + length = ONECODE_DESCENDER_HEIGHT; + break; + case 'A': + y += ONECODE_ASCENDER_OFFSET; + length = ONECODE_ASCENDER_HEIGHT; + break; + case 'F': + y += ONECODE_FULL_OFFSET; + length = ONECODE_FULL_HEIGHT; + break; + default: + break; + } + width = ONECODE_BAR_WIDTH; + + gl_barcode_add_line (gbc, x, y, length, width); + + x += ONECODE_BAR_PITCH; + } + + g_free (code); + + gbc->width = x + ONECODE_HORIZ_MARGIN; + gbc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN; + + return gbc; +} + + +/*--------------------------------------------------------------------------*/ +/* PRIVATE. Generate string of symbols, representing barcode. */ +/*--------------------------------------------------------------------------*/ +static gchar * +onecode_code (const gchar *digits) +{ + Int104 value = {0}; + gint i; + guint crc11; + guint codeword[10]; + guint character[10]; + gint d, a; + GString *code; + gchar *ret; + + if ( !is_string_valid (digits) ) + { + return NULL; + } + + + /*-----------------------------------------------------------*/ + /* Step 1 -- Conversion of Data Fields into Binary Data */ + /*-----------------------------------------------------------*/ + + /* Step 1.a -- Routing Code */ + for ( i = 20; digits[i] != 0; i++ ) + { + int104_mult_uint (&value, 10); + int104_add_uint (&value, digits[i] - '0'); + } + switch ( i-20 ) + { + case 0: + break; + case 5: + int104_add_uint (&value, 1); + break; + case 9: + int104_add_uint (&value, 1); + int104_add_uint (&value, 100000); + break; + case 11: + int104_add_uint (&value, 1); + int104_add_uint (&value, 100000); + int104_add_uint64 (&value, 1000000000); + break; + default: + return NULL; /* Should not happen if length tests passed. */ + break; + } + + /* Step 1.b -- Tracking Code */ + int104_mult_uint (&value, 10); + int104_add_uint (&value, digits[0] - '0'); + int104_mult_uint (&value, 5); + int104_add_uint (&value, digits[1] - '0'); + + for ( i = 2; i < 20; i++ ) + { + int104_mult_uint (&value, 10); + int104_add_uint (&value, digits[i] - '0'); + } + + + /*-----------------------------------------------------------*/ + /* Step 2 -- Generation of 11-Bit CRC on Binary Data */ + /*-----------------------------------------------------------*/ + + crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.byte ); + + + /*-----------------------------------------------------------*/ + /* Step 3 -- Conversion of Binary Data to Codewords */ + /*-----------------------------------------------------------*/ + + codeword[9] = int104_div_uint (&value, 636); + for ( i = 8; i >= 1; i-- ) + { + codeword[i] = int104_div_uint (&value, 1365); + } + codeword[0] = int104_div_uint (&value, 659); + + + /*-----------------------------------------------------------*/ + /* Step 4 -- Inserting Additional Information into Codewords */ + /*-----------------------------------------------------------*/ + + codeword[9] *= 2; + codeword[0] += (crc11 & 0x400) ? 659 : 0; + + + /*-----------------------------------------------------------*/ + /* Step 5 -- Conversion from Codewords to Characters */ + /*-----------------------------------------------------------*/ + + for ( i = 0; i < 10; i++ ) + { + character[i] = character_table[ codeword[i] ]; + + if ( crc11 & (1<str); + g_string_free (code, TRUE); + + return ret; +} + + +/*--------------------------------------------------------------------------*/ +/* Validate if string is of proper length & contains only valid characters. */ +/*--------------------------------------------------------------------------*/ +static gboolean +is_string_valid (const gchar *digits) +{ + gchar *p; + gint str_length; + + if (!digits) { + return FALSE; + } + + str_length = strlen (digits); + if ( (str_length != 20) && + (str_length != 25) && + (str_length != 29) && + (str_length != 31) ) + { + return FALSE; + } + + for ( p = (gchar *)digits; *p != 0; p++ ) + { + if (!g_ascii_isdigit (*p)) + { + return FALSE; + } + } + + if (digits[1] > '4') + { + return FALSE; /* Invalid Barcode Identifier. */ + } + + return TRUE; +} + + +/*--------------------------------------------------------------------------*/ +/* Multiply 104 bit integer by unsigned int. */ +/*--------------------------------------------------------------------------*/ +static void +int104_mult_uint (Int104 *x, + guint y) +{ + gint i; + guint64 temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] * y + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Add unsigned int to 104 bit integer. */ +/*--------------------------------------------------------------------------*/ +static void +int104_add_uint (Int104 *x, + guint y) +{ + gint i; + guint temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] + (y & 0xFF) + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + y = y >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Add unsigned 64 bit integer to 104 bit integer. */ +/*--------------------------------------------------------------------------*/ +static void +int104_add_uint64 (Int104 *x, + guint64 y) +{ + gint i; + guint64 temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] + (y & 0xFF) + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + y = y >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Divide 104 bit integer by unsigned int. */ +/*--------------------------------------------------------------------------*/ +static guint +int104_div_uint (Int104 *x, + guint y) +{ + guint carry, tmp, i; + + carry = 0; + for ( i = 0; i < 13; i++ ) + { + tmp = x->byte[i] + (carry<<8); + x->byte[i] = tmp / y; + carry = tmp % y; + } + + return carry; +} + + +/*--------------------------------------------------------------------------*/ +/* Print hex representation of 104 bit integer. (For debugging) */ +/*--------------------------------------------------------------------------*/ +static void +int104_print (Int104 *x) +{ + gint i; + + for ( i = 0; i < 13; i++ ) + { + g_print ("%02x ", x->byte[i] & 0xFF); + } + g_print ("\n"); +} + + +/*************************************************************************** + ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence + ** + ** Inputs: + ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which + ** are right justified - ie: the leftmost 2 bits of the first byte do not + ** hold data and must be set to zero. + ** + ** Outputs: + ** return unsigned short - 11 bit Frame Check Sequence (right justified) + ** + ** From Appendix C of USPS publication USPS-B-3200E, 07/08/05. + ***************************************************************************/ +unsigned short +USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr ) +{ + unsigned short GeneratorPolynomial = 0x0F35; + unsigned short FrameCheckSequence = 0x07FF; + unsigned short Data; + int ByteIndex, Bit; + + /* Do most significant byte skipping the 2 most significant bits */ + Data = *ByteArrayPtr << 5; + ByteArrayPtr++; + for ( Bit = 2; Bit < 8; Bit++ ) + { + if ( (FrameCheckSequence ^ Data) & 0x400 ) + { + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } + else + { + FrameCheckSequence = (FrameCheckSequence << 1); + } + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + + /* Do rest of the bytes */ + for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ ) + { + Data = *ByteArrayPtr << 3; + ByteArrayPtr++; + for ( Bit = 0; Bit < 8; Bit++ ) + { + if ( (FrameCheckSequence ^ Data) & 0x0400 ) + { + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } + else + { + FrameCheckSequence = (FrameCheckSequence << 1); + } + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + } + + return FrameCheckSequence; +} + + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/bc-onecode.h b/src/bc-onecode.h new file mode 100644 index 00000000..dec3e3bc --- /dev/null +++ b/src/bc-onecode.h @@ -0,0 +1,48 @@ +/* + * bc-onecode.h + * Copyright (C) 2010 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gLabels is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gLabels. If not, see . + */ + +#ifndef __BC_ONECODE_H__ +#define __BC_ONECODE_H__ + +#include "bc.h" + +G_BEGIN_DECLS + +glBarcode *gl_barcode_onecode_new (const gchar *id, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *digits); + +G_END_DECLS + +#endif /* __BC_ONECODE_H__ */ + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ -- 2.39.5