1: <?php
2: /**
3: * Process.php
4: *
5: * @since 2015-02-21
6: * @category Library
7: * @package Barcode
8: * @author Nicola Asuni <info@tecnick.com>
9: * @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
10: * @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
11: * @link https://github.com/tecnickcom/tc-lib-barcode
12: *
13: * This file is part of tc-lib-barcode software library.
14: */
15:
16: namespace Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven;
17:
18: use \Com\Tecnick\Barcode\Exception as BarcodeException;
19: use \Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven\Data;
20:
21: /**
22: * Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven\Compaction
23: *
24: * Process for PdfFourOneSeven Barcode type class
25: *
26: * @since 2015-02-21
27: * @category Library
28: * @package Barcode
29: * @author Nicola Asuni <info@tecnick.com>
30: * @copyright 2010-2016 Nicola Asuni - Tecnick.com LTD
31: * @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
32: * @link https://github.com/tecnickcom/tc-lib-barcode
33: */
34: abstract class Compaction extends \Com\Tecnick\Barcode\Type\Square\PdfFourOneSeven\Sequence
35: {
36: /**
37: * Process Sub Text Compaction
38: *
39: * @param array $txtarr
40: * @param int $submode
41: * @param int $sub
42: * @param string $code
43: * @param int $key
44: * @param int $idx
45: * @param int $codelen
46: */
47: protected function processTextCompactionSub(&$txtarr, &$submode, $sub, $code, $key, $idx, $codelen)
48: {
49: // $sub is the new submode
50: if (((($idx + 1) == $codelen) || ((($idx + 1) < $codelen)
51: && (array_search(ord($code[($idx + 1)]), Data::$textsubmodes[$submode]) !== false)))
52: && (($sub == 3) || (($sub == 0) && ($submode == 1)))
53: ) {
54: // shift (temporary change only for this char)
55: if ($sub == 3) {
56: // shift to puntuaction
57: $txtarr[] = 29;
58: } else {
59: // shift from lower to alpha
60: $txtarr[] = 27;
61: }
62: } else {
63: // latch
64: $txtarr = array_merge($txtarr, Data::$textlatch[''.$submode.$sub]);
65: // set new submode
66: $submode = $sub;
67: }
68: // add characted code to array
69: $txtarr[] = $key;
70: }
71:
72: /**
73: * Process Text Compaction
74: *
75: * @param string $code Data to compact
76: * @param string $codewords Codewords
77: *
78: * @return array of codewords
79: */
80: protected function processTextCompaction($code, &$codewords)
81: {
82: $submode = 0; // default Alpha sub-mode
83: $txtarr = array(); // array of characters and sub-mode switching characters
84: $codelen = strlen($code);
85: for ($idx = 0; $idx < $codelen; ++$idx) {
86: $chval = ord($code[$idx]);
87: if (($key = array_search($chval, Data::$textsubmodes[$submode])) !== false) {
88: // we are on the same sub-mode
89: $txtarr[] = $key;
90: } else {
91: // the sub-mode is changed
92: for ($sub = 0; $sub < 4; ++$sub) {
93: // search new sub-mode
94: if (($sub != $submode) && (($key = array_search($chval, Data::$textsubmodes[$sub])) !== false)) {
95: $this->processTextCompactionSub($txtarr, $submode, $sub, $code, $key, $idx, $codelen);
96: }
97: }
98: }
99: }
100: $txtarrlen = count($txtarr);
101: if (($txtarrlen % 2) != 0) {
102: // add padding
103: $txtarr[] = 29;
104: ++$txtarrlen;
105: }
106: // calculate codewords
107: for ($idx = 0; $idx < $txtarrlen; $idx += 2) {
108: $codewords[] = (30 * $txtarr[$idx]) + $txtarr[($idx + 1)];
109: }
110: }
111:
112: /**
113: * Process Byte Compaction
114: *
115: * @param string $code Data to compact
116: * @param string $codewords Codewords
117: *
118: * @return array of codewords
119: */
120: protected function processByteCompaction($code, &$codewords)
121: {
122: while (($codelen = strlen($code)) > 0) {
123: if ($codelen > 6) {
124: $rest = substr($code, 6);
125: $code = substr($code, 0, 6);
126: $sublen = 6;
127: } else {
128: $rest = '';
129: $sublen = strlen($code);
130: }
131: if ($sublen == 6) {
132: $tdg = bcmul(''.ord($code[0]), '1099511627776');
133: $tdg = bcadd($tdg, bcmul(''.ord($code[1]), '4294967296'));
134: $tdg = bcadd($tdg, bcmul(''.ord($code[2]), '16777216'));
135: $tdg = bcadd($tdg, bcmul(''.ord($code[3]), '65536'));
136: $tdg = bcadd($tdg, bcmul(''.ord($code[4]), '256'));
137: $tdg = bcadd($tdg, ''.ord($code[5]));
138: // tmp array for the 6 bytes block
139: $cw6 = array();
140: for ($idx = 0; $idx < 5; ++$idx) {
141: $ddg = bcmod($tdg, '900');
142: $tdg = bcdiv($tdg, '900');
143: // prepend the value to the beginning of the array
144: array_unshift($cw6, $ddg);
145: }
146: // append the result array at the end
147: $codewords = array_merge($codewords, $cw6);
148: } else {
149: for ($idx = 0; $idx < $sublen; ++$idx) {
150: $codewords[] = ord($code[$idx]);
151: }
152: }
153: $code = $rest;
154: }
155: }
156:
157: /**
158: * Process Numeric Compaction
159: *
160: * @param string $code Data to compact
161: * @param string $codewords Codewords
162: *
163: * @return array of codewords
164: */
165: protected function processNumericCompaction($code, &$codewords)
166: {
167: while (($codelen = strlen($code)) > 0) {
168: $rest = '';
169: if ($codelen > 44) {
170: $rest = substr($code, 44);
171: $code = substr($code, 0, 44);
172: }
173: $tdg = '1'.$code;
174: do {
175: $ddg = bcmod($tdg, '900');
176: $tdg = bcdiv($tdg, '900');
177: array_unshift($codewords, $ddg);
178: } while ($tdg != '0');
179: $code = $rest;
180: }
181: }
182:
183: /**
184: * Compact data by mode
185: *
186: * @param int $mode Compaction mode number
187: * @param string $code Data to compact
188: * @param boolean $addmode If true add the mode codeword in the first position
189: *
190: * @return array of codewords
191: */
192: protected function getCompaction($mode, $code, $addmode = true)
193: {
194: $codewords = array(); // array of codewords to return
195: switch ($mode) {
196: case 900:
197: // Text Compaction mode latch
198: $this->processTextCompaction($code, $codewords);
199: break;
200: case 901:
201: case 924:
202: // Byte Compaction mode latch
203: $this->processByteCompaction($code, $codewords);
204: break;
205: case 902:
206: // Numeric Compaction mode latch
207: $this->processNumericCompaction($code, $codewords);
208: break;
209: case 913:
210: // Byte Compaction mode shift
211: $codewords[] = ord($code);
212: break;
213: }
214: if ($addmode) {
215: // add the compaction mode codeword at the beginning
216: array_unshift($codewords, $mode);
217: }
218: return $codewords;
219: }
220: }
221: