147 |
- |
1 |
<?php
|
|
|
2 |
/*
|
|
|
3 |
* BarCode Coder Library (BCC Library)
|
|
|
4 |
* BCCL Version 2.0
|
|
|
5 |
*
|
|
|
6 |
* Porting : PHP
|
|
|
7 |
* Version : 2.0.4
|
|
|
8 |
*
|
|
|
9 |
* Date : 2013-01-06
|
|
|
10 |
* Author : DEMONTE Jean-Baptiste <jbdemonte@gmail.com>
|
|
|
11 |
* HOUREZ Jonathan
|
|
|
12 |
*
|
|
|
13 |
* Date : 2013-12-24
|
|
|
14 |
* Leszek Boroch <borek@borek.net.pl>
|
|
|
15 |
* Modification in class Barcode128 to enable encoding extended characters
|
|
|
16 |
* (ASCII above 127). To use barcodes, keypad emulation must be enabled in scanner configuration
|
|
|
17 |
* (tested with Motorola/Symbol LS2208).
|
|
|
18 |
*
|
|
|
19 |
* Web site: http://barcode-coder.com/
|
|
|
20 |
* dual licence : http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html
|
|
|
21 |
* http://www.gnu.org/licenses/gpl.html
|
|
|
22 |
*/
|
|
|
23 |
|
|
|
24 |
class Barcode {
|
|
|
25 |
|
|
|
26 |
static public function gd($res, $color, $x, $y, $angle, $type, $datas, $width = null, $height = null){
|
|
|
27 |
return self::_draw(__FUNCTION__, $res, $color, $x, $y, $angle, $type, $datas, $width, $height);
|
|
|
28 |
}
|
|
|
29 |
|
|
|
30 |
static public function fpdf($res, $color, $x, $y, $angle, $type, $datas, $width = null, $height = null){
|
|
|
31 |
return self::_draw(__FUNCTION__, $res, $color, $x, $y, $angle, $type, $datas, $width, $height);
|
|
|
32 |
}
|
|
|
33 |
|
|
|
34 |
static public function raw($type, $datas) {
|
|
|
35 |
$digit = '';
|
|
|
36 |
$hri = '';
|
|
|
37 |
$code = '';
|
|
|
38 |
$crc = true;
|
|
|
39 |
$rect = false;
|
|
|
40 |
|
|
|
41 |
if (is_array($datas)){
|
|
|
42 |
foreach(array('code' => '', 'crc' => true, 'rect' => false) as $v => $def){
|
|
|
43 |
$$v = isset($datas[$v]) ? $datas[$v] : $def;
|
|
|
44 |
}
|
|
|
45 |
$code = $code;
|
|
|
46 |
} else {
|
|
|
47 |
$code = $datas;
|
|
|
48 |
}
|
|
|
49 |
if ($code == '') return false;
|
|
|
50 |
$code = (string) $code;
|
|
|
51 |
|
|
|
52 |
$type = strtolower($type);
|
|
|
53 |
|
|
|
54 |
switch($type){
|
|
|
55 |
case 'std25':
|
|
|
56 |
case 'int25':
|
|
|
57 |
$digit = BarcodeI25::getDigit($code, $crc, $type);
|
|
|
58 |
$hri = BarcodeI25::compute($code, $crc, $type);
|
|
|
59 |
break;
|
|
|
60 |
case 'ean8':
|
|
|
61 |
case 'ean13':
|
|
|
62 |
$digit = BarcodeEAN::getDigit($code, $type);
|
|
|
63 |
$hri = BarcodeEAN::compute($code, $type);
|
|
|
64 |
break;
|
|
|
65 |
case 'upc':
|
|
|
66 |
$digit = BarcodeUPC::getDigit($code);
|
|
|
67 |
$hri = BarcodeUPC::compute($code);
|
|
|
68 |
break;
|
|
|
69 |
case 'code11':
|
|
|
70 |
$digit = Barcode11::getDigit($code);
|
|
|
71 |
$hri = $code;
|
|
|
72 |
break;
|
|
|
73 |
case 'code39':
|
|
|
74 |
$digit = Barcode39::getDigit($code);
|
|
|
75 |
$hri = $code;
|
|
|
76 |
break;
|
|
|
77 |
case 'code93':
|
|
|
78 |
$digit = Barcode93::getDigit($code, $crc);
|
|
|
79 |
$hri = $code;
|
|
|
80 |
break;
|
|
|
81 |
case 'code128':
|
|
|
82 |
$digit = Barcode128::getDigit($code);
|
|
|
83 |
$hri = $code;
|
|
|
84 |
break;
|
|
|
85 |
case 'codabar':
|
|
|
86 |
$digit = BarcodeCodabar::getDigit($code);
|
|
|
87 |
$hri = $code;
|
|
|
88 |
break;
|
|
|
89 |
case 'msi':
|
|
|
90 |
$digit = BarcodeMSI::getDigit($code, $crc);
|
|
|
91 |
$hri = BarcodeMSI::compute($code, $crc);
|
|
|
92 |
break;
|
|
|
93 |
case 'datamatrix':
|
|
|
94 |
$digit = BarcodeDatamatrix::getDigit($code, $rect);
|
|
|
95 |
$hri = $code;
|
|
|
96 |
break;
|
|
|
97 |
}
|
|
|
98 |
|
|
|
99 |
return array($digit, $hri);
|
|
|
100 |
}
|
|
|
101 |
|
|
|
102 |
static private function _draw($call, $res, $color, $x, $y, $angle, $type, $datas, $width, $height){
|
|
|
103 |
$digit = '';
|
|
|
104 |
$hri = '';
|
|
|
105 |
|
|
|
106 |
list($digit, $hri) = self::raw($type, $datas);
|
|
|
107 |
|
|
|
108 |
$type = strtolower($type);
|
|
|
109 |
|
|
|
110 |
if ($digit == '') return false;
|
|
|
111 |
|
|
|
112 |
if ($type == 'datamatrix'){
|
|
|
113 |
$width = is_null($width) ? 5 : $width;
|
|
|
114 |
$height = $width;
|
|
|
115 |
} else {
|
|
|
116 |
$width = is_null($width) ? 1 : $width;
|
|
|
117 |
$height = is_null($height) ? 50 : $height;
|
|
|
118 |
$digit = self::bitStringTo2DArray($digit);
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
if ( $call == 'gd' ){
|
|
|
122 |
$result = self::digitToGDRenderer($res, $color, $x, $y, $angle, $width, $height, $digit);
|
|
|
123 |
} else if ( $call == 'fpdf' ){
|
|
|
124 |
$result = self::digitToFPDFRenderer($res, $color, $x, $y, $angle, $width, $height, $digit);
|
|
|
125 |
}
|
|
|
126 |
|
|
|
127 |
$result['hri'] = $hri;
|
|
|
128 |
return $result;
|
|
|
129 |
}
|
|
|
130 |
|
|
|
131 |
// convert a bit string to an array of array of bit char
|
|
|
132 |
public static function bitStringTo2DArray( $digit ){
|
|
|
133 |
$d = array();
|
|
|
134 |
$len = strlen($digit);
|
|
|
135 |
for($i=0; $i<$len; $i++) $d[$i] = $digit[$i];
|
|
|
136 |
return(array($d));
|
|
|
137 |
}
|
|
|
138 |
|
|
|
139 |
public static function digitToRenderer($fn, $xi, $yi, $angle, $mw, $mh, $digit){
|
|
|
140 |
$lines = count($digit);
|
|
|
141 |
$columns = count($digit[0]);
|
|
|
142 |
$angle = deg2rad(-$angle);
|
|
|
143 |
$cos = cos($angle);
|
|
|
144 |
$sin = sin($angle);
|
|
|
145 |
|
|
|
146 |
self::_rotate($columns * $mw / 2, $lines * $mh / 2, $cos, $sin , $x, $y);
|
|
|
147 |
$xi -=$x;
|
|
|
148 |
$yi -=$y;
|
|
|
149 |
for($y=0; $y<$lines; $y++){
|
|
|
150 |
$x = -1;
|
|
|
151 |
while($x < ($columns-1)) {
|
|
|
152 |
$x++;
|
|
|
153 |
if ($digit[$y][$x] == '1') {
|
|
|
154 |
$z = $x;
|
|
|
155 |
while(($z + 1 <$columns) && ($digit[$y][$z + 1] == '1')) {
|
|
|
156 |
$z++;
|
|
|
157 |
}
|
|
|
158 |
$x1 = $x * $mw;
|
|
|
159 |
$y1 = $y * $mh;
|
|
|
160 |
$x2 = ($z + 1) * $mw;
|
|
|
161 |
$y2 = ($y + 1) * $mh;
|
|
|
162 |
self::_rotate($x1, $y1, $cos, $sin, $xA, $yA);
|
|
|
163 |
self::_rotate($x2, $y1, $cos, $sin, $xB, $yB);
|
|
|
164 |
self::_rotate($x2, $y2, $cos, $sin, $xC, $yC);
|
|
|
165 |
self::_rotate($x1, $y2, $cos, $sin, $xD, $yD);
|
|
|
166 |
$fn(array(
|
|
|
167 |
$xA + $xi, $yA + $yi,
|
|
|
168 |
$xB + $xi, $yB + $yi,
|
|
|
169 |
$xC + $xi, $yC + $yi,
|
|
|
170 |
$xD + $xi, $yD + $yi
|
|
|
171 |
));
|
|
|
172 |
$x = $z + 1;
|
|
|
173 |
}
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
return self::result($xi, $yi, $columns, $lines, $mw, $mh, $cos, $sin);
|
|
|
177 |
}
|
|
|
178 |
|
|
|
179 |
// GD barcode renderer
|
|
|
180 |
private static function digitToGDRenderer($gd, $color, $xi, $yi, $angle, $mw, $mh, $digit){
|
|
|
181 |
$fn = function($points) use ($gd, $color) {
|
|
|
182 |
imagefilledpolygon($gd, $points, 4, $color);
|
|
|
183 |
};
|
|
|
184 |
return self::digitToRenderer($fn, $xi, $yi, $angle, $mw, $mh, $digit);
|
|
|
185 |
}
|
|
|
186 |
// FPDF barcode renderer
|
|
|
187 |
private static function digitToFPDFRenderer($pdf, $color, $xi, $yi, $angle, $mw, $mh, $digit){
|
|
|
188 |
if (!is_array($color)){
|
|
|
189 |
if (preg_match('`([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})`i', $color, $m)){
|
|
|
190 |
$color = array(hexdec($m[1]),hexdec($m[2]),hexdec($m[3]));
|
|
|
191 |
} else {
|
|
|
192 |
$color = array(0,0,0);
|
|
|
193 |
}
|
|
|
194 |
}
|
|
|
195 |
$color = array_values($color);
|
|
|
196 |
$pdf->SetDrawColor($color[0],$color[1],$color[2]);
|
|
|
197 |
$pdf->SetFillColor($color[0],$color[1],$color[2]);
|
|
|
198 |
|
|
|
199 |
$fn = function($points) use ($pdf)
|
|
|
200 |
{
|
|
|
201 |
$op = 'f';
|
|
|
202 |
$h = $pdf->h;
|
|
|
203 |
$k = $pdf->k;
|
|
|
204 |
$points_string = '';
|
|
|
205 |
for($i=0; $i < 8; $i+=2){
|
|
|
206 |
$points_string .= sprintf('%.2F %.2F', $points[$i]*$k, ($h-$points[$i+1])*$k);
|
|
|
207 |
$points_string .= $i ? ' l ' : ' m ';
|
|
|
208 |
}
|
|
|
209 |
$pdf->_out($points_string . $op);
|
|
|
210 |
};
|
|
|
211 |
return self::digitToRenderer($fn, $xi, $yi, $angle, $mw, $mh, $digit);
|
|
|
212 |
}
|
|
|
213 |
|
|
|
214 |
static private function result($xi, $yi, $columns, $lines, $mw, $mh, $cos, $sin){
|
|
|
215 |
self::_rotate(0, 0, $cos, $sin , $x1, $y1);
|
|
|
216 |
self::_rotate($columns * $mw, 0, $cos, $sin , $x2, $y2);
|
|
|
217 |
self::_rotate($columns * $mw, $lines * $mh, $cos, $sin , $x3, $y3);
|
|
|
218 |
self::_rotate(0, $lines * $mh, $cos, $sin , $x4, $y4);
|
|
|
219 |
|
|
|
220 |
return array(
|
|
|
221 |
'width' => $columns * $mw,
|
|
|
222 |
'height'=> $lines * $mh,
|
|
|
223 |
'p1' => array(
|
|
|
224 |
'x' => $xi + $x1,
|
|
|
225 |
'y' => $yi + $y1
|
|
|
226 |
),
|
|
|
227 |
'p2' => array(
|
|
|
228 |
'x' => $xi + $x2,
|
|
|
229 |
'y' => $yi + $y2
|
|
|
230 |
),
|
|
|
231 |
'p3' => array(
|
|
|
232 |
'x' => $xi + $x3,
|
|
|
233 |
'y' => $yi + $y3
|
|
|
234 |
),
|
|
|
235 |
'p4' => array(
|
|
|
236 |
'x' => $xi + $x4,
|
|
|
237 |
'y' => $yi + $y4
|
|
|
238 |
)
|
|
|
239 |
);
|
|
|
240 |
}
|
|
|
241 |
|
|
|
242 |
static private function _rotate($x1, $y1, $cos, $sin , &$x, &$y){
|
|
|
243 |
$x = $x1 * $cos - $y1 * $sin;
|
|
|
244 |
$y = $x1 * $sin + $y1 * $cos;
|
|
|
245 |
}
|
|
|
246 |
|
|
|
247 |
static public function rotate($x1, $y1, $angle , &$x, &$y){
|
|
|
248 |
$angle = deg2rad(-$angle);
|
|
|
249 |
$cos = cos($angle);
|
|
|
250 |
$sin = sin($angle);
|
|
|
251 |
$x = $x1 * $cos - $y1 * $sin;
|
|
|
252 |
$y = $x1 * $sin + $y1 * $cos;
|
|
|
253 |
}
|
|
|
254 |
}
|
|
|
255 |
|
|
|
256 |
class BarcodeI25 {
|
|
|
257 |
static private $encoding = array('NNWWN', 'WNNNW', 'NWNNW', 'WWNNN', 'NNWNW', 'WNWNN', 'NWWNN', 'NNNWW', 'WNNWN','NWNWN');
|
|
|
258 |
|
|
|
259 |
static public function compute($code, $crc, $type){
|
|
|
260 |
if (! $crc) {
|
|
|
261 |
if (strlen($code) % 2) $code = '0' . $code;
|
|
|
262 |
} else {
|
|
|
263 |
if ( ($type == 'int25') && (strlen($code) % 2 == 0) ) $code = '0' . $code;
|
|
|
264 |
$odd = true;
|
|
|
265 |
$sum = 0;
|
|
|
266 |
for($i=strlen($code)-1; $i>-1; $i--){
|
|
|
267 |
$v = intval($code[$i]);
|
|
|
268 |
$sum += $odd ? 3 * $v : $v;
|
|
|
269 |
$odd = ! $odd;
|
|
|
270 |
}
|
|
|
271 |
$code .= (string) ((10 - $sum % 10) % 10);
|
|
|
272 |
}
|
|
|
273 |
return($code);
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
static public function getDigit($code, $crc, $type){
|
|
|
277 |
$code = self::compute($code, $crc, $type);
|
|
|
278 |
if ($code == '') return($code);
|
|
|
279 |
$result = '';
|
|
|
280 |
|
|
|
281 |
if ($type == 'int25') { // Interleaved 2 of 5
|
|
|
282 |
// start
|
|
|
283 |
$result .= '1010';
|
|
|
284 |
|
|
|
285 |
// digits + CRC
|
|
|
286 |
$end = strlen($code) / 2;
|
|
|
287 |
for($i=0; $i<$end; $i++){
|
|
|
288 |
$c1 = $code[2*$i];
|
|
|
289 |
$c2 = $code[2*$i+1];
|
|
|
290 |
for($j=0; $j<5; $j++){
|
|
|
291 |
$result .= '1';
|
|
|
292 |
if (self::$encoding[$c1][$j] == 'W') $result .= '1';
|
|
|
293 |
$result .= '0';
|
|
|
294 |
if (self::$encoding[$c2][$j] == 'W') $result .= '0';
|
|
|
295 |
}
|
|
|
296 |
}
|
|
|
297 |
// stop
|
|
|
298 |
$result .= '1101';
|
|
|
299 |
} else if ($type == 'std25') {
|
|
|
300 |
// Standard 2 of 5 is a numeric-only barcode that has been in use a long time.
|
|
|
301 |
// Unlike Interleaved 2 of 5, all of the information is encoded in the bars; the spaces are fixed width and are used only to separate the bars.
|
|
|
302 |
// The code is self-checking and does not include a checksum.
|
|
|
303 |
|
|
|
304 |
// start
|
|
|
305 |
$result .= '11011010';
|
|
|
306 |
|
|
|
307 |
// digits + CRC
|
|
|
308 |
$end = strlen($code);
|
|
|
309 |
for($i=0; $i<$end; $i++){
|
|
|
310 |
$c = $code[$i];
|
|
|
311 |
for($j=0; $j<5; $j++){
|
|
|
312 |
$result .= '1';
|
|
|
313 |
if (self::$encoding[$c][$j] == 'W') $result .= '11';
|
|
|
314 |
$result .= '0';
|
|
|
315 |
}
|
|
|
316 |
}
|
|
|
317 |
// stop
|
|
|
318 |
$result .= '11010110';
|
|
|
319 |
}
|
|
|
320 |
return($result);
|
|
|
321 |
}
|
|
|
322 |
}
|
|
|
323 |
|
|
|
324 |
|
|
|
325 |
class BarcodeEAN {
|
|
|
326 |
static private $encoding = array(
|
|
|
327 |
array('0001101', '0100111', '1110010'),
|
|
|
328 |
array('0011001', '0110011', '1100110'),
|
|
|
329 |
array('0010011', '0011011', '1101100'),
|
|
|
330 |
array('0111101', '0100001', '1000010'),
|
|
|
331 |
array('0100011', '0011101', '1011100'),
|
|
|
332 |
array('0110001', '0111001', '1001110'),
|
|
|
333 |
array('0101111', '0000101', '1010000'),
|
|
|
334 |
array('0111011', '0010001', '1000100'),
|
|
|
335 |
array('0110111', '0001001', '1001000'),
|
|
|
336 |
array('0001011', '0010111', '1110100')
|
|
|
337 |
);
|
|
|
338 |
|
|
|
339 |
static private $first = array('000000','001011','001101','001110','010011','011001','011100','010101','010110','011010');
|
|
|
340 |
|
|
|
341 |
static public function getDigit($code, $type){
|
|
|
342 |
// Check len (12 for ean13, 7 for ean8)
|
|
|
343 |
$len = $type == 'ean8' ? 7 : 12;
|
|
|
344 |
$code = substr($code, 0, $len);
|
|
|
345 |
if (!preg_match('`[0-9]{'.$len.'}`', $code)) return('');
|
|
|
346 |
|
|
|
347 |
// get checksum
|
|
|
348 |
$code = self::compute($code, $type);
|
|
|
349 |
|
|
|
350 |
// process analyse
|
|
|
351 |
$result = '101'; // start
|
|
|
352 |
|
|
|
353 |
if ($type == 'ean8'){
|
|
|
354 |
// process left part
|
|
|
355 |
for($i=0; $i<4; $i++){
|
|
|
356 |
$result .= self::$encoding[intval($code[$i])][0];
|
|
|
357 |
}
|
|
|
358 |
|
|
|
359 |
// center guard bars
|
|
|
360 |
$result .= '01010';
|
|
|
361 |
|
|
|
362 |
// process right part
|
|
|
363 |
for($i=4; $i<8; $i++){
|
|
|
364 |
$result .= self::$encoding[intval($code[$i])][2];
|
|
|
365 |
}
|
|
|
366 |
|
|
|
367 |
} else { // ean13
|
|
|
368 |
// extract first digit and get sequence
|
|
|
369 |
$seq = self::$first[ intval($code[0]) ];
|
|
|
370 |
|
|
|
371 |
// process left part
|
|
|
372 |
for($i=1; $i<7; $i++){
|
|
|
373 |
$result .= self::$encoding[intval($code[$i])][ intval($seq[$i-1]) ];
|
|
|
374 |
}
|
|
|
375 |
|
|
|
376 |
// center guard bars
|
|
|
377 |
$result .= '01010';
|
|
|
378 |
|
|
|
379 |
// process right part
|
|
|
380 |
for($i=7; $i<13; $i++){
|
|
|
381 |
$result .= self::$encoding[intval($code[$i])][ 2 ];
|
|
|
382 |
}
|
|
|
383 |
} // ean13
|
|
|
384 |
|
|
|
385 |
$result .= '101'; // stop
|
|
|
386 |
return($result);
|
|
|
387 |
}
|
|
|
388 |
|
|
|
389 |
static public function compute($code, $type){
|
|
|
390 |
$len = $type == 'ean13' ? 12 : 7;
|
|
|
391 |
$code = substr($code, 0, $len);
|
|
|
392 |
if (!preg_match('`[0-9]{'.$len.'}`', $code)) return('');
|
|
|
393 |
$sum = 0;
|
|
|
394 |
$odd = true;
|
|
|
395 |
for($i=$len-1; $i>-1; $i--){
|
|
|
396 |
$sum += ($odd ? 3 : 1) * intval($code[$i]);
|
|
|
397 |
$odd = ! $odd;
|
|
|
398 |
}
|
|
|
399 |
return($code . ( (string) ((10 - $sum % 10) % 10)));
|
|
|
400 |
}
|
|
|
401 |
}
|
|
|
402 |
|
|
|
403 |
class BarcodeUPC {
|
|
|
404 |
|
|
|
405 |
static public function getDigit($code){
|
|
|
406 |
if (strlen($code) < 12) {
|
|
|
407 |
$code = '0' . $code;
|
|
|
408 |
}
|
|
|
409 |
return BarcodeEAN::getDigit($code, 'ean13');
|
|
|
410 |
}
|
|
|
411 |
|
|
|
412 |
static public function compute($code){
|
|
|
413 |
if (strlen($code) < 12) {
|
|
|
414 |
$code = '0' . $code;
|
|
|
415 |
}
|
|
|
416 |
return substr(BarcodeEAN::compute($code, 'ean13'), 1);
|
|
|
417 |
}
|
|
|
418 |
}
|
|
|
419 |
|
|
|
420 |
class BarcodeMSI {
|
|
|
421 |
static private $encoding = array(
|
|
|
422 |
'100100100100', '100100100110', '100100110100', '100100110110',
|
|
|
423 |
'100110100100', '100110100110', '100110110100', '100110110110',
|
|
|
424 |
'110100100100', '110100100110');
|
|
|
425 |
|
|
|
426 |
static public function compute($code, $crc){
|
|
|
427 |
if (is_array($crc)){
|
|
|
428 |
if ($crc['crc1'] == 'mod10'){
|
|
|
429 |
$code = self::computeMod10($code);
|
|
|
430 |
} else if ($crc['crc1'] == 'mod11'){
|
|
|
431 |
$code = self::computeMod11($code);
|
|
|
432 |
}
|
|
|
433 |
if ($crc['crc2'] == 'mod10'){
|
|
|
434 |
$code = self::computeMod10($code);
|
|
|
435 |
} else if ($crc['crc2'] == 'mod11'){
|
|
|
436 |
$code = self::computeMod11($code);
|
|
|
437 |
}
|
|
|
438 |
} else if ($crc){
|
|
|
439 |
$code = self::computeMod10($code);
|
|
|
440 |
}
|
|
|
441 |
return($code);
|
|
|
442 |
}
|
|
|
443 |
|
|
|
444 |
static private function computeMod10($code){
|
|
|
445 |
$len = strlen($code);
|
|
|
446 |
$toPart1 = $len % 2;
|
|
|
447 |
$n1 = 0;
|
|
|
448 |
$sum = 0;
|
|
|
449 |
for($i=0; $i<$len; $i++){
|
|
|
450 |
if ($toPart1) {
|
|
|
451 |
$n1 = 10 * $n1 + intval($code[$i]);
|
|
|
452 |
} else {
|
|
|
453 |
$sum += intval($code[$i]);
|
|
|
454 |
}
|
|
|
455 |
$toPart1 = ! $toPart1;
|
|
|
456 |
}
|
|
|
457 |
$s1 = (string) (2 * $n1);
|
|
|
458 |
$len = strlen($s1);
|
|
|
459 |
for($i=0; $i<$len; $i++){
|
|
|
460 |
$sum += intval($s1[$i]);
|
|
|
461 |
}
|
|
|
462 |
return($code . ( (string) (10 - $sum % 10) % 10));
|
|
|
463 |
}
|
|
|
464 |
|
|
|
465 |
static private function computeMod11($code){
|
|
|
466 |
$sum = 0;
|
|
|
467 |
$weight = 2;
|
|
|
468 |
for($i=strlen($code)-1; $i>-1; $i--){
|
|
|
469 |
$sum += $weight * intval($code[$i]);
|
|
|
470 |
$weight = $weight == 7 ? 2 : $weight + 1;
|
|
|
471 |
}
|
|
|
472 |
return($code . ( (string) (11 - $sum % 11) % 11) );
|
|
|
473 |
}
|
|
|
474 |
|
|
|
475 |
static public function getDigit($code, $crc){
|
|
|
476 |
if (preg_match('`[^0-9]`', $code)) return '';
|
|
|
477 |
$index = 0;
|
|
|
478 |
$result = '';
|
|
|
479 |
|
|
|
480 |
$code = self::compute($code, false);
|
|
|
481 |
|
|
|
482 |
// start
|
|
|
483 |
$result = '110';
|
|
|
484 |
|
|
|
485 |
// digits
|
|
|
486 |
$len = strlen($code);
|
|
|
487 |
for($i=0; $i<$len; $i++){
|
|
|
488 |
$result .= self::$encoding[ intval($code[$i]) ];
|
|
|
489 |
}
|
|
|
490 |
|
|
|
491 |
// stop
|
|
|
492 |
$result .= '1001';
|
|
|
493 |
|
|
|
494 |
return($result);
|
|
|
495 |
}
|
|
|
496 |
}
|
|
|
497 |
|
|
|
498 |
class Barcode11 {
|
|
|
499 |
static private $encoding = array(
|
|
|
500 |
'101011', '1101011', '1001011', '1100101',
|
|
|
501 |
'1011011', '1101101', '1001101', '1010011',
|
|
|
502 |
'1101001', '110101', '101101');
|
|
|
503 |
|
|
|
504 |
static public function getDigit($code){
|
|
|
505 |
if (preg_match('`[^0-9\-]`', $code)) return '';
|
|
|
506 |
$result = '';
|
|
|
507 |
$intercharacter = '0';
|
|
|
508 |
|
|
|
509 |
// start
|
|
|
510 |
$result = '1011001' . $intercharacter;
|
|
|
511 |
|
|
|
512 |
// digits
|
|
|
513 |
$len = strlen($code);
|
|
|
514 |
for($i=0; $i<$len; $i++){
|
|
|
515 |
$index = $code[$i] == '-' ? 10 : intval($code[$i]);
|
|
|
516 |
$result .= self::$encoding[ $index ] . $intercharacter;
|
|
|
517 |
}
|
|
|
518 |
|
|
|
519 |
// checksum
|
|
|
520 |
$weightC = 0;
|
|
|
521 |
$weightSumC = 0;
|
|
|
522 |
$weightK = 1; // start at 1 because the right-most character is 'C' checksum
|
|
|
523 |
$weightSumK = 0;
|
|
|
524 |
for($i=$len-1; $i>-1; $i--){
|
|
|
525 |
$weightC = $weightC == 10 ? 1 : $weightC + 1;
|
|
|
526 |
$weightK = $weightK == 10 ? 1 : $weightK + 1;
|
|
|
527 |
|
|
|
528 |
$index = $code[$i] == '-' ? 10 : intval($code[$i]);
|
|
|
529 |
|
|
|
530 |
$weightSumC += $weightC * $index;
|
|
|
531 |
$weightSumK += $weightK * $index;
|
|
|
532 |
}
|
|
|
533 |
|
|
|
534 |
$c = $weightSumC % 11;
|
|
|
535 |
$weightSumK += $c;
|
|
|
536 |
$k = $weightSumK % 11;
|
|
|
537 |
|
|
|
538 |
$result .= self::$encoding[$c] . $intercharacter;
|
|
|
539 |
|
|
|
540 |
if ($len >= 10){
|
|
|
541 |
$result .= self::$encoding[$k] . $intercharacter;
|
|
|
542 |
}
|
|
|
543 |
|
|
|
544 |
// stop
|
|
|
545 |
$result .= '1011001';
|
|
|
546 |
|
|
|
547 |
return($result);
|
|
|
548 |
}
|
|
|
549 |
}
|
|
|
550 |
|
|
|
551 |
class Barcode39 {
|
|
|
552 |
static private $encoding = array(
|
|
|
553 |
'101001101101', '110100101011', '101100101011', '110110010101',
|
|
|
554 |
'101001101011', '110100110101', '101100110101', '101001011011',
|
|
|
555 |
'110100101101', '101100101101', '110101001011', '101101001011',
|
|
|
556 |
'110110100101', '101011001011', '110101100101', '101101100101',
|
|
|
557 |
'101010011011', '110101001101', '101101001101', '101011001101',
|
|
|
558 |
'110101010011', '101101010011', '110110101001', '101011010011',
|
|
|
559 |
'110101101001', '101101101001', '101010110011', '110101011001',
|
|
|
560 |
'101101011001', '101011011001', '110010101011', '100110101011',
|
|
|
561 |
'110011010101', '100101101011', '110010110101', '100110110101',
|
|
|
562 |
'100101011011', '110010101101', '100110101101', '100100100101',
|
|
|
563 |
'100100101001', '100101001001', '101001001001', '100101101101');
|
|
|
564 |
static public function getDigit($code){
|
|
|
565 |
$table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*';
|
|
|
566 |
$result = '';
|
|
|
567 |
$intercharacter = '0';
|
|
|
568 |
|
|
|
569 |
if (strpos($code, '*') !== false) return('');
|
|
|
570 |
|
|
|
571 |
// Add Start and Stop charactere : *
|
|
|
572 |
$code = strtoupper('*' . $code . '*');
|
|
|
573 |
|
|
|
574 |
$len = strlen($code);
|
|
|
575 |
for($i=0; $i<$len; $i++){
|
|
|
576 |
$index = strpos($table, $code[$i]);
|
|
|
577 |
if ($index === false) return('');
|
|
|
578 |
if ($i > 0) $result .= $intercharacter;
|
|
|
579 |
$result .= self::$encoding[ $index ];
|
|
|
580 |
}
|
|
|
581 |
return($result);
|
|
|
582 |
}
|
|
|
583 |
}
|
|
|
584 |
|
|
|
585 |
class Barcode93{
|
|
|
586 |
static private $encoding = array(
|
|
|
587 |
'100010100', '101001000', '101000100', '101000010',
|
|
|
588 |
'100101000', '100100100', '100100010', '101010000',
|
|
|
589 |
'100010010', '100001010', '110101000', '110100100',
|
|
|
590 |
'110100010', '110010100', '110010010', '110001010',
|
|
|
591 |
'101101000', '101100100', '101100010', '100110100',
|
|
|
592 |
'100011010', '101011000', '101001100', '101000110',
|
|
|
593 |
'100101100', '100010110', '110110100', '110110010',
|
|
|
594 |
'110101100', '110100110', '110010110', '110011010',
|
|
|
595 |
'101101100', '101100110', '100110110', '100111010',
|
|
|
596 |
'100101110', '111010100', '111010010', '111001010',
|
|
|
597 |
'101101110', '101110110', '110101110', '100100110',
|
|
|
598 |
'111011010', '111010110', '100110010', '101011110');
|
|
|
599 |
|
|
|
600 |
static public function getDigit($code, $crc){
|
|
|
601 |
$table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%____*'; // _ => ($), (%), (/) et (+)
|
|
|
602 |
$result = '';
|
|
|
603 |
|
|
|
604 |
if (strpos($code, '*') !== false) return('');
|
|
|
605 |
|
|
|
606 |
$code = strtoupper($code);
|
|
|
607 |
|
|
|
608 |
// start : *
|
|
|
609 |
$result .= self::$encoding[47];
|
|
|
610 |
|
|
|
611 |
// digits
|
|
|
612 |
$len = strlen($code);
|
|
|
613 |
for($i=0; $i<$len; $i++){
|
|
|
614 |
$c = $code[$i];
|
|
|
615 |
$index = strpos($table, $c);
|
|
|
616 |
if ( ($c == '_') || ($index === false) ) return('');
|
|
|
617 |
$result .= self::$encoding[ $index ];
|
|
|
618 |
}
|
|
|
619 |
|
|
|
620 |
// checksum
|
|
|
621 |
if ($crc){
|
|
|
622 |
$weightC = 0;
|
|
|
623 |
$weightSumC = 0;
|
|
|
624 |
$weightK = 1; // start at 1 because the right-most character is 'C' checksum
|
|
|
625 |
$weightSumK = 0;
|
|
|
626 |
for($i=$len-1; $i>-1; $i--){
|
|
|
627 |
$weightC = $weightC == 20 ? 1 : $weightC + 1;
|
|
|
628 |
$weightK = $weightK == 15 ? 1 : $weightK + 1;
|
|
|
629 |
|
|
|
630 |
$index = strpos($table, $code[$i]);
|
|
|
631 |
|
|
|
632 |
$weightSumC += $weightC * $index;
|
|
|
633 |
$weightSumK += $weightK * $index;
|
|
|
634 |
}
|
|
|
635 |
|
|
|
636 |
$c = $weightSumC % 47;
|
|
|
637 |
$weightSumK += $c;
|
|
|
638 |
$k = $weightSumK % 47;
|
|
|
639 |
|
|
|
640 |
$result .= self::$encoding[$c];
|
|
|
641 |
$result .= self::$encoding[$k];
|
|
|
642 |
}
|
|
|
643 |
|
|
|
644 |
// stop : *
|
|
|
645 |
$result .= self::$encoding[47];
|
|
|
646 |
|
|
|
647 |
// Terminaison bar
|
|
|
648 |
$result .= '1';
|
|
|
649 |
return($result);
|
|
|
650 |
}
|
|
|
651 |
}
|
|
|
652 |
|
|
|
653 |
class Barcode128 {
|
|
|
654 |
static private $encoding = array(
|
|
|
655 |
// descriptive encoding array, helpful when debugging
|
|
|
656 |
// Value Table A Table B Table C ASCII Code Character Pattern
|
|
|
657 |
'11011001100', // 0 Space Space 00 0032 or 0212 Space or O 11011001100
|
|
|
658 |
'11001101100', // 1 ! ! 01 0033 ! 11001101100
|
|
|
659 |
'11001100110', // 2 " " 02 0034 " 11001100110
|
|
|
660 |
'10010011000', // 3 # # 03 0035 # 10010011000
|
|
|
661 |
'10010001100', // 4 $ $ 04 0036 $ 10010001100
|
|
|
662 |
'10001001100', // 5 % % 05 0037 % 10001001100
|
|
|
663 |
'10011001000', // 6 & & 06 0038 & 10011001000
|
|
|
664 |
'10011000100', // 7 ' ' 07 0039 ' 10011000100
|
|
|
665 |
'10001100100', // 8 ( ( 08 0040 ( 10001100100
|
|
|
666 |
'11001001000', // 9 ) ) 09 0041 ) 11001001000
|
|
|
667 |
'11001000100', // 10 * * 10 0042 * 11001000100
|
|
|
668 |
'11000100100', // 11 + + 11 0043 + 11000100100
|
|
|
669 |
'10110011100', // 12 , , 12 0044 , 10110011100
|
|
|
670 |
'10011011100', // 13 - - 13 0045 - 10011011100
|
|
|
671 |
'10011001110', // 14 . . 14 0046 . 10011001110
|
|
|
672 |
'10111001100', // 15 / / 15 0047 / 10111001100
|
|
|
673 |
'10011101100', // 16 0 0 16 0048 0 10011101100
|
|
|
674 |
'10011100110', // 17 1 1 17 0049 1 10011100110
|
|
|
675 |
'11001110010', // 18 2 2 18 0050 2 11001110010
|
|
|
676 |
'11001011100', // 19 3 3 19 0051 3 11001011100
|
|
|
677 |
'11001001110', // 20 4 4 20 0052 4 11001001110
|
|
|
678 |
'11011100100', // 21 5 5 21 0053 5 11011100100
|
|
|
679 |
'11001110100', // 22 6 6 22 0054 6 11001110100
|
|
|
680 |
'11101101110', // 23 7 7 23 0055 7 11101101110
|
|
|
681 |
'11101001100', // 24 8 8 24 0056 8 11101001100
|
|
|
682 |
'11100101100', // 25 9 9 25 0057 9 11100101100
|
|
|
683 |
'11100100110', // 26 : : 26 0058 : 11100100110
|
|
|
684 |
'11101100100', // 27 ; ; 27 0059 ; 11101100100
|
|
|
685 |
'11100110100', // 28 < < 28 0060 < 11100110100
|
|
|
686 |
'11100110010', // 29 = = 29 0061 = 11100110010
|
|
|
687 |
'11011011000', // 30 > > 30 0062 > 11011011000
|
|
|
688 |
'11011000110', // 31 ? ? 31 0063 ? 11011000110
|
|
|
689 |
'11000110110', // 32 @ @ 32 0064 @ 11000110110
|
|
|
690 |
'10100011000', // 33 A A 33 0065 A 10100011000
|
|
|
691 |
'10001011000', // 34 B B 34 0066 B 10001011000
|
|
|
692 |
'10001000110', // 35 C C 35 0067 C 10001000110
|
|
|
693 |
'10110001000', // 36 D D 36 0068 D 10110001000
|
|
|
694 |
'10001101000', // 37 E E 37 0069 E 10001101000
|
|
|
695 |
'10001100010', // 38 F F 38 0070 F 10001100010
|
|
|
696 |
'11010001000', // 39 G G 39 0071 G 11010001000
|
|
|
697 |
'11000101000', // 40 H H 40 0072 H 11000101000
|
|
|
698 |
'11000100010', // 41 I I 41 0073 I 11000100010
|
|
|
699 |
'10110111000', // 42 J J 42 0074 J 10110111000
|
|
|
700 |
'10110001110', // 43 K K 43 0075 K 10110001110
|
|
|
701 |
'10001101110', // 44 L L 44 0076 L 10001101110
|
|
|
702 |
'10111011000', // 45 M M 45 0077 M 10111011000
|
|
|
703 |
'10111000110', // 46 N N 46 0078 N 10111000110
|
|
|
704 |
'10001110110', // 47 O O 47 0079 O 10001110110
|
|
|
705 |
'11101110110', // 48 P P 48 0080 P 11101110110
|
|
|
706 |
'11010001110', // 49 Q Q 49 0081 Q 11010001110
|
|
|
707 |
'11000101110', // 50 R R 50 0082 R 11000101110
|
|
|
708 |
'11011101000', // 51 S S 51 0083 S 11011101000
|
|
|
709 |
'11011100010', // 52 T T 52 0084 T 11011100010
|
|
|
710 |
'11011101110', // 53 U U 53 0085 U 11011101110
|
|
|
711 |
'11101011000', // 54 V V 54 0086 V 11101011000
|
|
|
712 |
'11101000110', // 55 W W 55 0087 W 11101000110
|
|
|
713 |
'11100010110', // 56 X X 56 0088 X 11100010110
|
|
|
714 |
'11101101000', // 57 Y Y 57 0089 Y 11101101000
|
|
|
715 |
'11101100010', // 58 Z Z 58 0090 Z 11101100010
|
|
|
716 |
'11100011010', // 59 [ [ 59 0091 [ 11100011010
|
|
|
717 |
'11101111010', // 60 \ \ 60 0092 \ 11101111010
|
|
|
718 |
'11001000010', // 61 ] ] 61 0093 ] 11001000010
|
|
|
719 |
'11110001010', // 62 ^ ^ 62 0094 ^ 11110001010
|
|
|
720 |
'10100110000', // 63 _ _ 63 0095 _ 10100110000
|
|
|
721 |
'10100001100', // 64 nul ` 64 0096 ` 10100001100
|
|
|
722 |
'10010110000', // 65 soh a 65 0097 a 10010110000
|
|
|
723 |
'10010000110', // 66 stx b 66 0098 b 10010000110
|
|
|
724 |
'10000101100', // 67 etx c 67 0099 c 10000101100
|
|
|
725 |
'10000100110', // 68 eot d 68 0100 d 10000100110
|
|
|
726 |
'10110010000', // 69 eno e 69 0101 e 10110010000
|
|
|
727 |
'10110000100', // 70 ack f 70 0102 f 10110000100
|
|
|
728 |
'10011010000', // 71 bel g 71 0103 g 10011010000
|
|
|
729 |
'10011000010', // 72 bs h 72 0104 h 10011000010
|
|
|
730 |
'10000110100', // 73 ht i 73 0105 i 10000110100
|
|
|
731 |
'10000110010', // 74 lf j 74 0106 j 10000110010
|
|
|
732 |
'11000010010', // 75 vt k 75 0107 k 11000010010
|
|
|
733 |
'11001010000', // 76 ff l 76 0108 l 11001010000
|
|
|
734 |
'11110111010', // 77 cr m 77 0109 m 11110111010
|
|
|
735 |
'11000010100', // 78 s0 n 78 0110 n 11000010100
|
|
|
736 |
'10001111010', // 79 s1 o 79 0111 o 10001111010
|
|
|
737 |
'10100111100', // 80 dle p 80 0112 p 10100111100
|
|
|
738 |
'10010111100', // 81 dc1 q 81 0113 q 10010111100
|
|
|
739 |
'10010011110', // 82 dc2 r 82 0114 r 10010011110
|
|
|
740 |
'10111100100', // 83 dc3 s 83 0115 s 10111100100
|
|
|
741 |
'10011110100', // 84 dc4 t 84 0116 t 10011110100
|
|
|
742 |
'10011110010', // 85 nak u 85 0117 u 10011110010
|
|
|
743 |
'11110100100', // 86 syn v 86 0118 v 11110100100
|
|
|
744 |
'11110010100', // 87 etb w 87 0119 w 11110010100
|
|
|
745 |
'11110010010', // 88 can x 88 0120 x 11110010010
|
|
|
746 |
'11011011110', // 89 em y 89 0121 y 11011011110
|
|
|
747 |
'11011110110', // 90 sub z 90 0122 z 11011110110
|
|
|
748 |
'11110110110', // 91 esc { 91 0123 { 11110110110
|
|
|
749 |
'10101111000', // 92 fs | 92 0124 | 10101111000
|
|
|
750 |
'10100011110', // 93 gs } 93 0125 } 10100011110
|
|
|
751 |
'10001011110', // 94 rs ~ 94 0126 ~ 10001011110
|
|
|
752 |
'10111101000', // 95 us del 95 0200 E 10111101000
|
|
|
753 |
'10111100010', // 96 Fnc 3 Fnc 3 96 0201 E 10111100010
|
|
|
754 |
'11110101000', // 97 Fnc 2 Fnc2 97 0202 E 11110101000
|
|
|
755 |
'11110100010', // 98 Shift Shift 98 0203 E 11110100010
|
|
|
756 |
'10111011110', // 99 Code C Code C 99 0204 I 10111011110
|
|
|
757 |
'10111101110', // 100 Code B Fnc 4 Code B 0205 I 10111101110
|
|
|
758 |
'11101011110', // 101 Fnc 4 Code A Code A 0206 I 11101011110
|
|
|
759 |
'11110101110', // 102 Fnc 1 Fnc 1 Fnc 1 0207 I 11110101110
|
|
|
760 |
'11010000100', // 103 Start A Start A Start A 0208 D 11010000100
|
|
|
761 |
'11010010000', // 104 Start B Start B Start B 0209 N 11010010000
|
|
|
762 |
'11010011100', // 105 Start C Start C Start C 0210 O 11010011100
|
|
|
763 |
'11000111010' // 106 Stop Stop Stop 0211 O 1100011101011
|
|
|
764 |
);
|
|
|
765 |
static public function getDigit($code){
|
|
|
766 |
$tableB = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
|
|
767 |
$result = "";
|
|
|
768 |
$sum = 0;
|
|
|
769 |
$isum = 0;
|
|
|
770 |
$i = 0;
|
|
|
771 |
$j = 0;
|
|
|
772 |
$value = 0;
|
|
|
773 |
|
|
|
774 |
// check each characters
|
|
|
775 |
$len = strlen($code);
|
|
|
776 |
// we allow now extended ASCII so no need to check against table B
|
|
|
777 |
// for($i=0; $i<$len; $i++){
|
|
|
778 |
// if (strpos($tableB, $code[$i]) === false) return("");
|
|
|
779 |
// }
|
|
|
780 |
|
|
|
781 |
// check firsts characters : start with C table only if enough numeric
|
|
|
782 |
$tableCActivated = $len> 1;
|
|
|
783 |
$c = '';
|
|
|
784 |
for($i=0; $i<3 && $i<$len; $i++){
|
|
|
785 |
$tableCActivated &= preg_match('`[0-9]`', $code[$i]);
|
|
|
786 |
}
|
|
|
787 |
|
|
|
788 |
$sum = $tableCActivated ? 105 : 104;
|
|
|
789 |
|
|
|
790 |
// start : [105] : C table or [104] : B table
|
|
|
791 |
$result = self::$encoding[ $sum ];
|
|
|
792 |
|
|
|
793 |
$i = 0;
|
|
|
794 |
while( $i < $len ){
|
|
|
795 |
if (! $tableCActivated){
|
|
|
796 |
$j = 0;
|
|
|
797 |
// check next character to activate C table if interresting
|
|
|
798 |
while ( ($i + $j < $len) && preg_match('`[0-9]`', $code[$i+$j]) ) $j++;
|
|
|
799 |
|
|
|
800 |
// 6 min everywhere or 4 mini at the end
|
|
|
801 |
$tableCActivated = ($j > 5) || (($i + $j - 1 == $len) && ($j > 3));
|
|
|
802 |
|
|
|
803 |
if ( $tableCActivated ){
|
|
|
804 |
$result .= self::$encoding[ 99 ]; // C table
|
|
|
805 |
$sum += ++$isum * 99;
|
|
|
806 |
}
|
|
|
807 |
// 2 min for table C so need table B
|
|
|
808 |
} else if ( ($i == $len - 1) || (preg_match('`[^0-9]`', $code[$i])) || (preg_match('`[^0-9]`', $code[$i+1])) ) { //todo : verifier le JS : len - 1!!! XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
|
809 |
$tableCActivated = false;
|
|
|
810 |
$result .= self::$encoding[ 100 ]; // B table
|
|
|
811 |
$sum += ++$isum * 100;
|
|
|
812 |
}
|
|
|
813 |
|
|
|
814 |
if ( $tableCActivated ) {
|
|
|
815 |
$value = intval(substr($code, $i, 2)); // Add two characters (numeric)
|
|
|
816 |
$i += 2;
|
|
|
817 |
} else {
|
|
|
818 |
// take care of extended characters (ASCII above 127)
|
|
|
819 |
if (ord($code[$i])>126) {
|
|
|
820 |
$result .= self::$encoding[ 100 ];
|
|
|
821 |
$sum += ++$isum * 100;
|
|
|
822 |
$value = strpos($tableB, chr(ord($code[$i])-128)); // Add one character
|
|
|
823 |
} else {
|
|
|
824 |
$value = strpos($tableB, $code[$i]); // Add one character
|
|
|
825 |
}
|
|
|
826 |
$i++;
|
|
|
827 |
}
|
|
|
828 |
$result .= self::$encoding[ $value ];
|
|
|
829 |
$sum += ++$isum * $value;
|
|
|
830 |
}
|
|
|
831 |
|
|
|
832 |
// Add CRC
|
|
|
833 |
$result .= self::$encoding[ $sum % 103 ];
|
|
|
834 |
|
|
|
835 |
// Stop
|
|
|
836 |
$result .= self::$encoding[ 106 ];
|
|
|
837 |
|
|
|
838 |
// Termination bar
|
|
|
839 |
$result .= '11';
|
|
|
840 |
|
|
|
841 |
return($result);
|
|
|
842 |
}
|
|
|
843 |
}
|
|
|
844 |
|
|
|
845 |
class BarcodeCodabar {
|
|
|
846 |
static private $encoding = array(
|
|
|
847 |
'101010011', '101011001', '101001011', '110010101',
|
|
|
848 |
'101101001', '110101001', '100101011', '100101101',
|
|
|
849 |
'100110101', '110100101', '101001101', '101100101',
|
|
|
850 |
'1101011011', '1101101011', '1101101101', '1011011011',
|
|
|
851 |
'1011001001', '1010010011', '1001001011', '1010011001');
|
|
|
852 |
|
|
|
853 |
static public function getDigit($code){
|
|
|
854 |
$table = '0123456789-$:/.+';
|
|
|
855 |
$result = '';
|
|
|
856 |
$intercharacter = '0';
|
|
|
857 |
|
|
|
858 |
// add start : A->D : arbitrary choose A
|
|
|
859 |
$result .= self::$encoding[16] . $intercharacter;
|
|
|
860 |
|
|
|
861 |
$len = strlen($code);
|
|
|
862 |
for($i=0; $i<$len; $i++){
|
|
|
863 |
$index = strpos($table, $code[$i]);
|
|
|
864 |
if ($index === false) return('');
|
|
|
865 |
$result .= self::$encoding[ $index ] . $intercharacter;
|
|
|
866 |
}
|
|
|
867 |
|
|
|
868 |
// add stop : A->D : arbitrary choose A
|
|
|
869 |
$result .= self::$encoding[16];
|
|
|
870 |
return($result);
|
|
|
871 |
}
|
|
|
872 |
}
|
|
|
873 |
|
|
|
874 |
class BarcodeDatamatrix {
|
|
|
875 |
static private $lengthRows = array(
|
|
|
876 |
10, 12, 14, 16, 18, 20, 22, 24, 26, // 24 squares et 6 rectangular
|
|
|
877 |
32, 36, 40, 44, 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144,
|
|
|
878 |
8, 8, 12, 12, 16, 16);
|
|
|
879 |
static private $lengthCols = array(
|
|
|
880 |
10, 12, 14, 16, 18, 20, 22, 24, 26, // Number of columns for the entire datamatrix
|
|
|
881 |
32, 36, 40, 44, 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144,
|
|
|
882 |
18, 32, 26, 36, 36, 48);
|
|
|
883 |
static private $dataCWCount = array(
|
|
|
884 |
3, 5, 8, 12, 18, 22, 30, 36, // Number of data codewords for the datamatrix
|
|
|
885 |
44, 62, 86, 114, 144, 174, 204, 280, 368, 456, 576, 696, 816, 1050,
|
|
|
886 |
1304, 1558, 5, 10, 16, 22, 32, 49);
|
|
|
887 |
static private $solomonCWCount = array(
|
|
|
888 |
5, 7, 10, 12, 14, 18, 20, 24, 28, // Number of Reed-Solomon codewords for the datamatrix
|
|
|
889 |
36, 42, 48, 56, 68, 84, 112, 144, 192, 224, 272, 336, 408, 496, 620,
|
|
|
890 |
7, 11, 14, 18, 24, 28);
|
|
|
891 |
static private $dataRegionRows = array(
|
|
|
892 |
8, 10, 12, 14, 16, 18, 20, 22, // Number of rows per region
|
|
|
893 |
24, 14, 16, 18, 20, 22, 24, 14, 16, 18, 20, 22, 24, 18, 20, 22,
|
|
|
894 |
6, 6, 10, 10, 14, 14);
|
|
|
895 |
static private $dataRegionCols = array(
|
|
|
896 |
8, 10, 12, 14, 16, 18, 20, 22, // Number of columns per region
|
|
|
897 |
24, 14, 16, 18, 20, 22, 24, 14, 16, 18, 20, 22, 24, 18, 20, 22,
|
|
|
898 |
16, 14, 24, 16, 16, 22);
|
|
|
899 |
static private $regionRows = array(
|
|
|
900 |
1, 1, 1, 1, 1, 1, 1, 1, // Number of regions per row
|
|
|
901 |
1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 6, 6, 6,
|
|
|
902 |
1, 1, 1, 1, 1, 1);
|
|
|
903 |
static private $regionCols = array(
|
|
|
904 |
1, 1, 1, 1, 1, 1, 1, 1, // Number of regions per column
|
|
|
905 |
1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 6, 6, 6,
|
|
|
906 |
1, 2, 1, 2, 2, 2);
|
|
|
907 |
static private $interleavedBlocks = array(
|
|
|
908 |
1, 1, 1, 1, 1, 1, 1, 1, // Number of blocks
|
|
|
909 |
1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 6, 6, 8, 8,
|
|
|
910 |
1, 1, 1, 1, 1, 1);
|
|
|
911 |
static private $logTab = array(
|
|
|
912 |
-255, 255, 1, 240, 2, 225, 241, 53, 3, // Table of log for the Galois field
|
|
|
913 |
38, 226, 133, 242, 43, 54, 210, 4, 195, 39, 114, 227, 106, 134, 28,
|
|
|
914 |
243, 140, 44, 23, 55, 118, 211, 234, 5, 219, 196, 96, 40, 222, 115,
|
|
|
915 |
103, 228, 78, 107, 125, 135, 8, 29, 162, 244, 186, 141, 180, 45, 99,
|
|
|
916 |
24, 49, 56, 13, 119, 153, 212, 199, 235, 91, 6, 76, 220, 217, 197,
|
|
|
917 |
11, 97, 184, 41, 36, 223, 253, 116, 138, 104, 193, 229, 86, 79, 171,
|
|
|
918 |
108, 165, 126, 145, 136, 34, 9, 74, 30, 32, 163, 84, 245, 173, 187,
|
|
|
919 |
204, 142, 81, 181, 190, 46, 88, 100, 159, 25, 231, 50, 207, 57, 147,
|
|
|
920 |
14, 67, 120, 128, 154, 248, 213, 167, 200, 63, 236, 110, 92, 176, 7,
|
|
|
921 |
161, 77, 124, 221, 102, 218, 95, 198, 90, 12, 152, 98, 48, 185, 179,
|
|
|
922 |
42, 209, 37, 132, 224, 52, 254, 239, 117, 233, 139, 22, 105, 27, 194,
|
|
|
923 |
113, 230, 206, 87, 158, 80, 189, 172, 203, 109, 175, 166, 62, 127,
|
|
|
924 |
247, 146, 66, 137, 192, 35, 252, 10, 183, 75, 216, 31, 83, 33, 73,
|
|
|
925 |
164, 144, 85, 170, 246, 65, 174, 61, 188, 202, 205, 157, 143, 169, 82,
|
|
|
926 |
72, 182, 215, 191, 251, 47, 178, 89, 151, 101, 94, 160, 123, 26, 112,
|
|
|
927 |
232, 21, 51, 238, 208, 131, 58, 69, 148, 18, 15, 16, 68, 17, 121, 149,
|
|
|
928 |
129, 19, 155, 59, 249, 70, 214, 250, 168, 71, 201, 156, 64, 60, 237,
|
|
|
929 |
130, 111, 20, 93, 122, 177, 150);
|
|
|
930 |
static private $aLogTab = array(
|
|
|
931 |
1, 2, 4, 8, 16, 32, 64, 128, 45, 90, // Table of aLog for the Galois field
|
|
|
932 |
180, 69, 138, 57, 114, 228, 229, 231, 227, 235, 251, 219, 155, 27, 54,
|
|
|
933 |
108, 216, 157, 23, 46, 92, 184, 93, 186, 89, 178, 73, 146, 9, 18, 36,
|
|
|
934 |
72, 144, 13, 26, 52, 104, 208, 141, 55, 110, 220, 149, 7, 14, 28, 56,
|
|
|
935 |
112, 224, 237, 247, 195, 171, 123, 246, 193, 175, 115, 230, 225, 239,
|
|
|
936 |
243, 203, 187, 91, 182, 65, 130, 41, 82, 164, 101, 202, 185, 95, 190,
|
|
|
937 |
81, 162, 105, 210, 137, 63, 126, 252, 213, 135, 35, 70, 140, 53, 106,
|
|
|
938 |
212, 133, 39, 78, 156, 21, 42, 84, 168, 125, 250, 217, 159, 19, 38, 76,
|
|
|
939 |
152, 29, 58, 116, 232, 253, 215, 131, 43, 86, 172, 117, 234, 249, 223,
|
|
|
940 |
147, 11, 22, 44, 88, 176, 77, 154, 25, 50, 100, 200, 189, 87, 174, 113,
|
|
|
941 |
226, 233, 255, 211, 139, 59, 118, 236, 245, 199, 163, 107, 214, 129,
|
|
|
942 |
47, 94, 188, 85, 170, 121, 242, 201, 191, 83, 166, 97, 194, 169, 127,
|
|
|
943 |
254, 209, 143, 51, 102, 204, 181, 71, 142, 49, 98, 196, 165, 103, 206,
|
|
|
944 |
177, 79, 158, 17, 34, 68, 136, 61, 122, 244, 197, 167, 99, 198, 161,
|
|
|
945 |
111, 222, 145, 15, 30, 60, 120, 240, 205, 183, 67, 134, 33, 66, 132,
|
|
|
946 |
37, 74, 148, 5, 10, 20, 40, 80, 160, 109, 218, 153, 31, 62, 124, 248,
|
|
|
947 |
221, 151, 3, 6, 12, 24, 48, 96, 192, 173, 119, 238, 241, 207, 179, 75,
|
|
|
948 |
150, 1);
|
|
|
949 |
static private function champGaloisMult($a, $b){ // MULTIPLICATION IN GALOIS FIELD GF(2^8)
|
|
|
950 |
if(!$a || !$b) return 0;
|
|
|
951 |
return self::$aLogTab[(self::$logTab[$a] + self::$logTab[$b]) % 255];
|
|
|
952 |
}
|
|
|
953 |
static private function champGaloisDoub($a, $b){ // THE OPERATION a * 2^b IN GALOIS FIELD GF(2^8)
|
|
|
954 |
if (!$a) return 0;
|
|
|
955 |
if (!$b) return $a;
|
|
|
956 |
return self::$aLogTab[(self::$logTab[$a] + $b) % 255];
|
|
|
957 |
}
|
|
|
958 |
static private function champGaloisSum($a, $b){ // SUM IN GALOIS FIELD GF(2^8)
|
|
|
959 |
return $a ^ $b;
|
|
|
960 |
}
|
|
|
961 |
static private function selectIndex($dataCodeWordsCount, $rectangular){ // CHOOSE THE GOOD INDEX FOR TABLES
|
|
|
962 |
if (($dataCodeWordsCount<1 || $dataCodeWordsCount>1558) && !$rectangular) return -1;
|
|
|
963 |
if (($dataCodeWordsCount<1 || $dataCodeWordsCount>49) && $rectangular) return -1;
|
|
|
964 |
|
|
|
965 |
$n = $rectangular ? 24 : 0;
|
|
|
966 |
|
|
|
967 |
while (self::$dataCWCount[$n] < $dataCodeWordsCount) $n++;
|
|
|
968 |
return $n;
|
|
|
969 |
}
|
|
|
970 |
static private function encodeDataCodeWordsASCII($text) {
|
|
|
971 |
$dataCodeWords = array();
|
|
|
972 |
$n = 0;
|
|
|
973 |
$len = strlen($text);
|
|
|
974 |
for ($i=0; $i<$len; $i++){
|
|
|
975 |
$c = ord($text[$i]);
|
|
|
976 |
if ($c > 127) {
|
|
|
977 |
$dataCodeWords[$n] = 235;
|
|
|
978 |
$c -= 127;
|
|
|
979 |
$n++;
|
|
|
980 |
} else if (($c>=48 && $c<=57) && ($i+1<$len) && (preg_match('`[0-9]`', $text[$i+1]))) {
|
|
|
981 |
$c = (($c - 48) * 10) + intval($text[$i+1]);
|
|
|
982 |
$c += 130;
|
|
|
983 |
$i++;
|
|
|
984 |
} else $c++;
|
|
|
985 |
$dataCodeWords[$n] = $c;
|
|
|
986 |
$n++;
|
|
|
987 |
}
|
|
|
988 |
return $dataCodeWords;
|
|
|
989 |
}
|
|
|
990 |
static private function addPadCW(&$tab, $from, $to){
|
|
|
991 |
if ($from >= $to) return ;
|
|
|
992 |
$tab[$from] = 129;
|
|
|
993 |
for ($i=$from+1; $i<$to; $i++){
|
|
|
994 |
$r = ((149 * ($i+1)) % 253) + 1;
|
|
|
995 |
$tab[$i] = (129 + $r) % 254;
|
|
|
996 |
}
|
|
|
997 |
}
|
|
|
998 |
static private function calculSolFactorTable($solomonCWCount){ // CALCULATE THE REED SOLOMON FACTORS
|
|
|
999 |
$g = array_fill(0, $solomonCWCount+1, 1);
|
|
|
1000 |
for($i = 1; $i <= $solomonCWCount; $i++) {
|
|
|
1001 |
for($j = $i - 1; $j >= 0; $j--) {
|
|
|
1002 |
$g[$j] = self::champGaloisDoub($g[$j], $i);
|
|
|
1003 |
if($j > 0) $g[$j] = self::champGaloisSum($g[$j], $g[$j-1]);
|
|
|
1004 |
}
|
|
|
1005 |
}
|
|
|
1006 |
return $g;
|
|
|
1007 |
}
|
|
|
1008 |
static private function addReedSolomonCW($nSolomonCW, $coeffTab, $nDataCW, &$dataTab, $blocks){ // Add the Reed Solomon codewords
|
|
|
1009 |
$errorBlocks = $nSolomonCW / $blocks;
|
|
|
1010 |
$correctionCW = array();
|
|
|
1011 |
|
|
|
1012 |
for($k = 0; $k < $blocks; $k++) {
|
|
|
1013 |
for ($i=0; $i < $errorBlocks; $i++) $correctionCW[$i] = 0;
|
|
|
1014 |
|
|
|
1015 |
for ($i=$k; $i<$nDataCW; $i+=$blocks){
|
|
|
1016 |
$temp = self::champGaloisSum($dataTab[$i], $correctionCW[$errorBlocks-1]);
|
|
|
1017 |
for ($j=$errorBlocks-1; $j>=0; $j--){
|
|
|
1018 |
if ( !$temp ) {
|
|
|
1019 |
$correctionCW[$j] = 0;
|
|
|
1020 |
} else {
|
|
|
1021 |
$correctionCW[$j] = self::champGaloisMult($temp, $coeffTab[$j]);
|
|
|
1022 |
}
|
|
|
1023 |
if ($j>0) $correctionCW[$j] = self::champGaloisSum($correctionCW[$j-1], $correctionCW[$j]);
|
|
|
1024 |
}
|
|
|
1025 |
}
|
|
|
1026 |
// Renversement des blocs calcules
|
|
|
1027 |
$j = $nDataCW + $k;
|
|
|
1028 |
for ($i=$errorBlocks-1; $i>=0; $i--){
|
|
|
1029 |
$dataTab[$j] = $correctionCW[$i];
|
|
|
1030 |
$j=$j+$blocks;
|
|
|
1031 |
}
|
|
|
1032 |
}
|
|
|
1033 |
return $dataTab;
|
|
|
1034 |
}
|
|
|
1035 |
static private function getBits($entier){ // Transform integer to tab of bits
|
|
|
1036 |
$bits = array();
|
|
|
1037 |
for ($i=0; $i<8; $i++){
|
|
|
1038 |
$bits[$i] = $entier & (128 >> $i) ? 1 : 0;
|
|
|
1039 |
}
|
|
|
1040 |
return $bits;
|
|
|
1041 |
}
|
|
|
1042 |
static private function next($etape, $totalRows, $totalCols, $codeWordsBits, &$datamatrix, &$assigned){ // Place codewords into the matrix
|
|
|
1043 |
$chr = 0; // Place of the 8st bit from the first character to [4][0]
|
|
|
1044 |
$row = 4;
|
|
|
1045 |
$col = 0;
|
|
|
1046 |
|
|
|
1047 |
do {
|
|
|
1048 |
// Check for a special case of corner
|
|
|
1049 |
if(($row == $totalRows) && ($col == 0)){
|
|
|
1050 |
self::patternShapeSpecial1($datamatrix, $assigned, $codeWordsBits[$chr], $totalRows, $totalCols);
|
|
|
1051 |
$chr++;
|
|
|
1052 |
} else if(($etape<3) && ($row == $totalRows-2) && ($col == 0) && ($totalCols%4 != 0)){
|
|
|
1053 |
self::patternShapeSpecial2($datamatrix, $assigned, $codeWordsBits[$chr], $totalRows, $totalCols);
|
|
|
1054 |
$chr++;
|
|
|
1055 |
} else if(($row == $totalRows-2) && ($col == 0) && ($totalCols%8 == 4)){
|
|
|
1056 |
self::patternShapeSpecial3($datamatrix, $assigned, $codeWordsBits[$chr], $totalRows, $totalCols);
|
|
|
1057 |
$chr++;
|
|
|
1058 |
}
|
|
|
1059 |
else if(($row == $totalRows+4) && ($col == 2) && ($totalCols%8 == 0)){
|
|
|
1060 |
self::patternShapeSpecial4($datamatrix, $assigned, $codeWordsBits[$chr], $totalRows, $totalCols);
|
|
|
1061 |
$chr++;
|
|
|
1062 |
}
|
|
|
1063 |
|
|
|
1064 |
// Go up and right in the datamatrix
|
|
|
1065 |
do {
|
|
|
1066 |
if(($row < $totalRows) && ($col >= 0) && (!isset($assigned[$row][$col]) || $assigned[$row][$col]!=1)) {
|
|
|
1067 |
self::patternShapeStandard($datamatrix, $assigned, $codeWordsBits[$chr], $row, $col, $totalRows, $totalCols);
|
|
|
1068 |
$chr++;
|
|
|
1069 |
}
|
|
|
1070 |
$row -= 2;
|
|
|
1071 |
$col += 2;
|
|
|
1072 |
} while (($row >= 0) && ($col < $totalCols));
|
|
|
1073 |
$row += 1;
|
|
|
1074 |
$col += 3;
|
|
|
1075 |
|
|
|
1076 |
// Go down and left in the datamatrix
|
|
|
1077 |
do {
|
|
|
1078 |
if(($row >= 0) && ($col < $totalCols) && (!isset($assigned[$row][$col]) || $assigned[$row][$col]!=1)){
|
|
|
1079 |
self::patternShapeStandard($datamatrix, $assigned, $codeWordsBits[$chr], $row, $col, $totalRows, $totalCols);
|
|
|
1080 |
$chr++;
|
|
|
1081 |
}
|
|
|
1082 |
$row += 2;
|
|
|
1083 |
$col -= 2;
|
|
|
1084 |
} while (($row < $totalRows) && ($col >=0));
|
|
|
1085 |
$row += 3;
|
|
|
1086 |
$col += 1;
|
|
|
1087 |
} while (($row < $totalRows) || ($col < $totalCols));
|
|
|
1088 |
}
|
|
|
1089 |
static private function patternShapeStandard(&$datamatrix, &$assigned, $bits, $row, $col, $totalRows, $totalCols){ // Place bits in the matrix (standard or special case)
|
|
|
1090 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[0], $row-2, $col-2, $totalRows, $totalCols);
|
|
|
1091 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[1], $row-2, $col-1, $totalRows, $totalCols);
|
|
|
1092 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[2], $row-1, $col-2, $totalRows, $totalCols);
|
|
|
1093 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[3], $row-1, $col-1, $totalRows, $totalCols);
|
|
|
1094 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[4], $row-1, $col, $totalRows, $totalCols);
|
|
|
1095 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[5], $row, $col-2, $totalRows, $totalCols);
|
|
|
1096 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[6], $row, $col-1, $totalRows, $totalCols);
|
|
|
1097 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[7], $row, $col, $totalRows, $totalCols);
|
|
|
1098 |
}
|
|
|
1099 |
static private function patternShapeSpecial1(&$datamatrix, &$assigned, $bits, $totalRows, $totalCols ){
|
|
|
1100 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[0], $totalRows-1, 0, $totalRows, $totalCols);
|
|
|
1101 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[1], $totalRows-1, 1, $totalRows, $totalCols);
|
|
|
1102 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[2], $totalRows-1, 2, $totalRows, $totalCols);
|
|
|
1103 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[3], 0, $totalCols-2, $totalRows, $totalCols);
|
|
|
1104 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[4], 0, $totalCols-1, $totalRows, $totalCols);
|
|
|
1105 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[5], 1, $totalCols-1, $totalRows, $totalCols);
|
|
|
1106 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[6], 2, $totalCols-1, $totalRows, $totalCols);
|
|
|
1107 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[7], 3, $totalCols-1, $totalRows, $totalCols);
|
|
|
1108 |
}
|
|
|
1109 |
static private function patternShapeSpecial2(&$datamatrix, &$assigned, $bits, $totalRows, $totalCols ){
|
|
|
1110 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[0], $totalRows-3, 0, $totalRows, $totalCols);
|
|
|
1111 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[1], $totalRows-2, 0, $totalRows, $totalCols);
|
|
|
1112 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[2], $totalRows-1, 0, $totalRows, $totalCols);
|
|
|
1113 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[3], 0, $totalCols-4, $totalRows, $totalCols);
|
|
|
1114 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[4], 0, $totalCols-3, $totalRows, $totalCols);
|
|
|
1115 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[5], 0, $totalCols-2, $totalRows, $totalCols);
|
|
|
1116 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[6], 0, $totalCols-1, $totalRows, $totalCols);
|
|
|
1117 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[7], 1, $totalCols-1, $totalRows, $totalCols);
|
|
|
1118 |
}
|
|
|
1119 |
static private function patternShapeSpecial3(&$datamatrix, &$assigned, $bits, $totalRows, $totalCols ){
|
|
|
1120 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[0], $totalRows-3, 0, $totalRows, $totalCols);
|
|
|
1121 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[1], $totalRows-2, 0, $totalRows, $totalCols);
|
|
|
1122 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[2], $totalRows-1, 0, $totalRows, $totalCols);
|
|
|
1123 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[3], 0, $totalCols-2, $totalRows, $totalCols);
|
|
|
1124 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[4], 0, $totalCols-1, $totalRows, $totalCols);
|
|
|
1125 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[5], 1, $totalCols-1, $totalRows, $totalCols);
|
|
|
1126 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[6], 2, $totalCols-1, $totalRows, $totalCols);
|
|
|
1127 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[7], 3, $totalCols-1, $totalRows, $totalCols);
|
|
|
1128 |
}
|
|
|
1129 |
static private function patternShapeSpecial4(&$datamatrix, &$assigned, $bits, $totalRows, $totalCols ){
|
|
|
1130 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[0], $totalRows-1, 0, $totalRows, $totalCols);
|
|
|
1131 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[1], $totalRows-1, $totalCols-1, $totalRows, $totalCols);
|
|
|
1132 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[2], 0, $totalCols-3, $totalRows, $totalCols);
|
|
|
1133 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[3], 0, $totalCols-2, $totalRows, $totalCols);
|
|
|
1134 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[4], 0, $totalCols-1, $totalRows, $totalCols);
|
|
|
1135 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[5], 1, $totalCols-3, $totalRows, $totalCols);
|
|
|
1136 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[6], 1, $totalCols-2, $totalRows, $totalCols);
|
|
|
1137 |
self::placeBitInDatamatrix($datamatrix, $assigned, $bits[7], 1, $totalCols-1, $totalRows, $totalCols);
|
|
|
1138 |
}
|
|
|
1139 |
static private function placeBitInDatamatrix(&$datamatrix, &$assigned, $bit, $row, $col, $totalRows, $totalCols){ // Put a bit into the matrix
|
|
|
1140 |
if ($row < 0) {
|
|
|
1141 |
$row += $totalRows;
|
|
|
1142 |
$col += 4 - (($totalRows+4)%8);
|
|
|
1143 |
}
|
|
|
1144 |
if ($col < 0) {
|
|
|
1145 |
$col += $totalCols;
|
|
|
1146 |
$row += 4 - (($totalCols+4)%8);
|
|
|
1147 |
}
|
|
|
1148 |
if (!isset($assigned[$row][$col]) || $assigned[$row][$col] != 1) {
|
|
|
1149 |
$datamatrix[$row][$col] = $bit;
|
|
|
1150 |
$assigned[$row][$col] = 1;
|
|
|
1151 |
}
|
|
|
1152 |
}
|
|
|
1153 |
static private function addFinderPattern($datamatrix, $rowsRegion, $colsRegion, $rowsRegionCW, $colsRegionCW){ // Add the finder pattern
|
|
|
1154 |
$totalRowsCW = ($rowsRegionCW+2) * $rowsRegion;
|
|
|
1155 |
$totalColsCW = ($colsRegionCW+2) * $colsRegion;
|
|
|
1156 |
|
|
|
1157 |
$datamatrixTemp = array();
|
|
|
1158 |
$datamatrixTemp[0] = array_fill(0, $totalColsCW+2, 0);
|
|
|
1159 |
|
|
|
1160 |
for ($i=0; $i<$totalRowsCW; $i++){
|
|
|
1161 |
$datamatrixTemp[$i+1] = array();
|
|
|
1162 |
$datamatrixTemp[$i+1][0] = 0;
|
|
|
1163 |
$datamatrixTemp[$i+1][$totalColsCW+1] = 0;
|
|
|
1164 |
for ($j=0; $j<$totalColsCW; $j++){
|
|
|
1165 |
if ($i%($rowsRegionCW+2) == 0){
|
|
|
1166 |
if ($j%2 == 0){
|
|
|
1167 |
$datamatrixTemp[$i+1][$j+1] = 1;
|
|
|
1168 |
} else {
|
|
|
1169 |
$datamatrixTemp[$i+1][$j+1] = 0;
|
|
|
1170 |
}
|
|
|
1171 |
} else if ($i%($rowsRegionCW+2) == $rowsRegionCW+1){
|
|
|
1172 |
$datamatrixTemp[$i+1][$j+1] = 1;
|
|
|
1173 |
} else if ($j%($colsRegionCW+2) == $colsRegionCW+1){
|
|
|
1174 |
if ($i%2 == 0){
|
|
|
1175 |
$datamatrixTemp[$i+1][$j+1] = 0;
|
|
|
1176 |
} else {
|
|
|
1177 |
$datamatrixTemp[$i+1][$j+1] = 1;
|
|
|
1178 |
}
|
|
|
1179 |
} else if ($j%($colsRegionCW+2) == 0){
|
|
|
1180 |
$datamatrixTemp[$i+1][$j+1] = 1;
|
|
|
1181 |
} else{
|
|
|
1182 |
$datamatrixTemp[$i+1][$j+1] = 0;
|
|
|
1183 |
$datamatrixTemp[$i+1][$j+1] = $datamatrix[$i-1-(2*(floor($i/($rowsRegionCW+2))))][$j-1-(2*(floor($j/($colsRegionCW+2))))]; // todo : parseInt => ?
|
|
|
1184 |
}
|
|
|
1185 |
}
|
|
|
1186 |
}
|
|
|
1187 |
$datamatrixTemp[$totalRowsCW+1] = array();
|
|
|
1188 |
for ($j=0; $j<$totalColsCW+2; $j++){
|
|
|
1189 |
$datamatrixTemp[$totalRowsCW+1][$j] = 0;
|
|
|
1190 |
}
|
|
|
1191 |
return $datamatrixTemp;
|
|
|
1192 |
}
|
|
|
1193 |
static public function getDigit($text, $rectangular){
|
|
|
1194 |
$dataCodeWords = self::encodeDataCodeWordsASCII($text); // Code the text in the ASCII mode
|
|
|
1195 |
$dataCWCount = count($dataCodeWords);
|
|
|
1196 |
$index = self::selectIndex($dataCWCount, $rectangular); // Select the index for the data tables
|
|
|
1197 |
$totalDataCWCount = self::$dataCWCount[$index]; // Number of data CW
|
|
|
1198 |
$solomonCWCount = self::$solomonCWCount[$index]; // Number of Reed Solomon CW
|
|
|
1199 |
$totalCWCount = $totalDataCWCount + $solomonCWCount; // Number of CW
|
|
|
1200 |
$rowsTotal = self::$lengthRows[$index]; // Size of symbol
|
|
|
1201 |
$colsTotal = self::$lengthCols[$index];
|
|
|
1202 |
$rowsRegion = self::$regionRows[$index]; // Number of region
|
|
|
1203 |
$colsRegion = self::$regionCols[$index];
|
|
|
1204 |
$rowsRegionCW = self::$dataRegionRows[$index];
|
|
|
1205 |
$colsRegionCW = self::$dataRegionCols[$index];
|
|
|
1206 |
$rowsLengthMatrice = $rowsTotal-2*$rowsRegion; // Size of matrice data
|
|
|
1207 |
$colsLengthMatrice = $colsTotal-2*$colsRegion;
|
|
|
1208 |
$blocks = self::$interleavedBlocks[$index]; // Number of Reed Solomon blocks
|
|
|
1209 |
$errorBlocks = $solomonCWCount / $blocks;
|
|
|
1210 |
|
|
|
1211 |
self::addPadCW($dataCodeWords, $dataCWCount, $totalDataCWCount); // Add codewords pads
|
|
|
1212 |
|
|
|
1213 |
$g = self::calculSolFactorTable($errorBlocks); // Calculate correction coefficients
|
|
|
1214 |
|
|
|
1215 |
self::addReedSolomonCW($solomonCWCount, $g, $totalDataCWCount, $dataCodeWords, $blocks); // Add Reed Solomon codewords
|
|
|
1216 |
|
|
|
1217 |
$codeWordsBits = array(); // Calculte bits from codewords
|
|
|
1218 |
for ($i=0; $i<$totalCWCount; $i++){
|
|
|
1219 |
$codeWordsBits[$i] = self::getBits($dataCodeWords[$i]);
|
|
|
1220 |
}
|
|
|
1221 |
|
|
|
1222 |
$datamatrix = array_fill(0, $colsLengthMatrice, array());
|
|
|
1223 |
$assigned = array_fill(0, $colsLengthMatrice, array());
|
|
|
1224 |
|
|
|
1225 |
// Add the bottom-right corner if needed
|
|
|
1226 |
if ( (($rowsLengthMatrice * $colsLengthMatrice) % 8) == 4) {
|
|
|
1227 |
$datamatrix[$rowsLengthMatrice-2][$colsLengthMatrice-2] = 1;
|
|
|
1228 |
$datamatrix[$rowsLengthMatrice-1][$colsLengthMatrice-1] = 1;
|
|
|
1229 |
$datamatrix[$rowsLengthMatrice-1][$colsLengthMatrice-2] = 0;
|
|
|
1230 |
$datamatrix[$rowsLengthMatrice-2][$colsLengthMatrice-1] = 0;
|
|
|
1231 |
$assigned[$rowsLengthMatrice-2][$colsLengthMatrice-2] = 1;
|
|
|
1232 |
$assigned[$rowsLengthMatrice-1][$colsLengthMatrice-1] = 1;
|
|
|
1233 |
$assigned[$rowsLengthMatrice-1][$colsLengthMatrice-2] = 1;
|
|
|
1234 |
$assigned[$rowsLengthMatrice-2][$colsLengthMatrice-1] = 1;
|
|
|
1235 |
}
|
|
|
1236 |
|
|
|
1237 |
// Put the codewords into the matrix
|
|
|
1238 |
self::next(0,$rowsLengthMatrice,$colsLengthMatrice, $codeWordsBits, $datamatrix, $assigned);
|
|
|
1239 |
|
|
|
1240 |
// Add the finder pattern
|
|
|
1241 |
$datamatrix = self::addFinderPattern($datamatrix, $rowsRegion, $colsRegion, $rowsRegionCW, $colsRegionCW);
|
|
|
1242 |
|
|
|
1243 |
return $datamatrix;
|
|
|
1244 |
}
|
|
|
1245 |
|
|
|
1246 |
static public function getLenghtColumn($text)
|
|
|
1247 |
{
|
|
|
1248 |
$dataCodeWords = self::encodeDataCodeWordsASCII($text);
|
|
|
1249 |
$dataCWCount = count($dataCodeWords);
|
|
|
1250 |
$index = self::selectIndex($dataCWCount, false);
|
|
|
1251 |
|
|
|
1252 |
return self::$lengthCols[$index];
|
|
|
1253 |
}
|
|
|
1254 |
}
|
|
|
1255 |
?>
|