|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 //============================================================+ 00003 // File name : barcodes.php 00004 // Version : 1.0.021 00005 // Begin : 2008-06-09 00006 // Last Update : 2011-09-15 00007 // Author : Nicola Asuni - Tecnick.com S.r.l - Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com 00008 // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html) 00009 // ------------------------------------------------------------------- 00010 // Copyright (C) 2008-2011 Nicola Asuni - Tecnick.com S.r.l. 00011 // 00012 // This file is part of TCPDF software library. 00013 // 00014 // TCPDF is free software: you can redistribute it and/or modify it 00015 // under the terms of the GNU Lesser General Public License as 00016 // published by the Free Software Foundation, either version 3 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // TCPDF is distributed in the hope that it will be useful, but 00020 // WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 // See the GNU Lesser General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU Lesser General Public License 00025 // along with TCPDF. If not, see <http://www.gnu.org/licenses/>. 00026 // 00027 // See LICENSE.TXT file for more information. 00028 // ------------------------------------------------------------------- 00029 // 00030 // Description : PHP class to creates array representations for 00031 // common 1D barcodes to be used with TCPDF. 00032 // 00033 //============================================================+ 00034 00050 class TCPDFBarcode { 00051 00056 protected $barcode_array; 00057 00073 public function __construct($code, $type) { 00074 $this->setBarcode($code, $type); 00075 } 00076 00082 public function getBarcodeArray() { 00083 return $this->barcode_array; 00084 } 00085 00093 public function getBarcodeSVG($w=2, $h=30, $color='black') { 00094 // send headers 00095 $code = $this->getBarcodeSVGcode($w, $h, $color); 00096 header('Content-Type: application/svg+xml'); 00097 header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 00098 header('Pragma: public'); 00099 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past 00100 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 00101 header('Content-Disposition: inline; filename="'.md5($code).'.svg";'); 00102 //header('Content-Length: '.strlen($code)); 00103 echo $code; 00104 } 00105 00114 public function getBarcodeSVGcode($w=2, $h=30, $color='black') { 00115 // replace table for special characters 00116 $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); 00117 $svg = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n"; 00118 $svg .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n"; 00119 $svg .= '<svg width="'.round(($this->barcode_array['maxw'] * $w), 3).'" height="'.$h.'" version="1.1" xmlns="http://www.w3.org/2000/svg">'."\n"; 00120 $svg .= "\t".'<desc>'.strtr($this->barcode_array['code'], $repstr).'</desc>'."\n"; 00121 $svg .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n"; 00122 // print bars 00123 $x = 0; 00124 foreach ($this->barcode_array['bcode'] as $k => $v) { 00125 $bw = round(($v['w'] * $w), 3); 00126 $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3); 00127 if ($v['t']) { 00128 $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3); 00129 // draw a vertical bar 00130 $svg .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$bw.'" height="'.$bh.'" />'."\n"; 00131 } 00132 $x += $bw; 00133 } 00134 $svg .= "\t".'</g>'."\n"; 00135 $svg .= '</svg>'."\n"; 00136 return $svg; 00137 } 00138 00147 public function getBarcodeHTML($w=2, $h=30, $color='black') { 00148 // replace table for special characters 00149 $html = '<div style="font-size:0;position:relative;">'."\n"; 00150 // print bars 00151 $x = 0; 00152 foreach ($this->barcode_array['bcode'] as $k => $v) { 00153 $bw = round(($v['w'] * $w), 3); 00154 $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3); 00155 if ($v['t']) { 00156 $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3); 00157 // draw a vertical bar 00158 $html .= '<div style="background-color:'.$color.';width:'.$bw.'px;height:'.$bh.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n"; 00159 } 00160 $x += $bw; 00161 } 00162 $html .= '</div>'."\n"; 00163 return $html; 00164 } 00165 00174 public function getBarcodePNG($w=2, $h=30, $color=array(0,0,0)) { 00175 // calculate image size 00176 $width = ($this->barcode_array['maxw'] * $w); 00177 $height = $h; 00178 if (function_exists('imagecreate')) { 00179 // GD library 00180 $imagick = false; 00181 $png = imagecreate($width, $height); 00182 $bgcol = imagecolorallocate($png, 255, 255, 255); 00183 imagecolortransparent($png, $bgcol); 00184 $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]); 00185 } elseif (extension_loaded('imagick')) { 00186 $imagick = true; 00187 $bgcol = new imagickpixel('rgb(255,255,255'); 00188 $fgcol = new imagickpixel('rgb('.$color[0].','.$color[1].','.$color[2].')'); 00189 $png = new Imagick(); 00190 $png->newImage($width, $height, 'none', 'png'); 00191 $bar = new imagickdraw(); 00192 $bar->setfillcolor($fgcol); 00193 } else { 00194 return false; 00195 } 00196 // print bars 00197 $x = 0; 00198 foreach ($this->barcode_array['bcode'] as $k => $v) { 00199 $bw = round(($v['w'] * $w), 3); 00200 $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3); 00201 if ($v['t']) { 00202 $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3); 00203 // draw a vertical bar 00204 if ($imagick) { 00205 $bar->rectangle($x, $y, ($x + $bw), ($y + $bh)); 00206 } else { 00207 imagefilledrectangle($png, $x, $y, ($x + $bw), ($y + $bh), $fgcol); 00208 } 00209 } 00210 $x += $bw; 00211 } 00212 // send headers 00213 header('Content-Type: image/png'); 00214 header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 00215 header('Pragma: public'); 00216 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past 00217 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 00218 if ($imagick) { 00219 $png->drawimage($bar); 00220 echo $png; 00221 } else { 00222 imagepng($png); 00223 imagedestroy($png); 00224 } 00225 } 00226 00234 public function setBarcode($code, $type) { 00235 switch (strtoupper($type)) { 00236 case 'C39': { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9. 00237 $arrcode = $this->barcode_code39($code, false, false); 00238 break; 00239 } 00240 case 'C39+': { // CODE 39 with checksum 00241 $arrcode = $this->barcode_code39($code, false, true); 00242 break; 00243 } 00244 case 'C39E': { // CODE 39 EXTENDED 00245 $arrcode = $this->barcode_code39($code, true, false); 00246 break; 00247 } 00248 case 'C39E+': { // CODE 39 EXTENDED + CHECKSUM 00249 $arrcode = $this->barcode_code39($code, true, true); 00250 break; 00251 } 00252 case 'C93': { // CODE 93 - USS-93 00253 $arrcode = $this->barcode_code93($code); 00254 break; 00255 } 00256 case 'S25': { // Standard 2 of 5 00257 $arrcode = $this->barcode_s25($code, false); 00258 break; 00259 } 00260 case 'S25+': { // Standard 2 of 5 + CHECKSUM 00261 $arrcode = $this->barcode_s25($code, true); 00262 break; 00263 } 00264 case 'I25': { // Interleaved 2 of 5 00265 $arrcode = $this->barcode_i25($code, false); 00266 break; 00267 } 00268 case 'I25+': { // Interleaved 2 of 5 + CHECKSUM 00269 $arrcode = $this->barcode_i25($code, true); 00270 break; 00271 } 00272 case 'C128': { // CODE 128 00273 $arrcode = $this->barcode_c128($code, ''); 00274 break; 00275 } 00276 case 'C128A': { // CODE 128 A 00277 $arrcode = $this->barcode_c128($code, 'A'); 00278 break; 00279 } 00280 case 'C128B': { // CODE 128 B 00281 $arrcode = $this->barcode_c128($code, 'B'); 00282 break; 00283 } 00284 case 'C128C': { // CODE 128 C 00285 $arrcode = $this->barcode_c128($code, 'C'); 00286 break; 00287 } 00288 case 'EAN2': { // 2-Digits UPC-Based Extention 00289 $arrcode = $this->barcode_eanext($code, 2); 00290 break; 00291 } 00292 case 'EAN5': { // 5-Digits UPC-Based Extention 00293 $arrcode = $this->barcode_eanext($code, 5); 00294 break; 00295 } 00296 case 'EAN8': { // EAN 8 00297 $arrcode = $this->barcode_eanupc($code, 8); 00298 break; 00299 } 00300 case 'EAN13': { // EAN 13 00301 $arrcode = $this->barcode_eanupc($code, 13); 00302 break; 00303 } 00304 case 'UPCA': { // UPC-A 00305 $arrcode = $this->barcode_eanupc($code, 12); 00306 break; 00307 } 00308 case 'UPCE': { // UPC-E 00309 $arrcode = $this->barcode_eanupc($code, 6); 00310 break; 00311 } 00312 case 'MSI': { // MSI (Variation of Plessey code) 00313 $arrcode = $this->barcode_msi($code, false); 00314 break; 00315 } 00316 case 'MSI+': { // MSI + CHECKSUM (modulo 11) 00317 $arrcode = $this->barcode_msi($code, true); 00318 break; 00319 } 00320 case 'POSTNET': { // POSTNET 00321 $arrcode = $this->barcode_postnet($code, false); 00322 break; 00323 } 00324 case 'PLANET': { // PLANET 00325 $arrcode = $this->barcode_postnet($code, true); 00326 break; 00327 } 00328 case 'RMS4CC': { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) 00329 $arrcode = $this->barcode_rms4cc($code, false); 00330 break; 00331 } 00332 case 'KIX': { // KIX (Klant index - Customer index) 00333 $arrcode = $this->barcode_rms4cc($code, true); 00334 break; 00335 } 00336 case 'IMB': { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 00337 $arrcode = $this->barcode_imb($code); 00338 break; 00339 } 00340 case 'CODABAR': { // CODABAR 00341 $arrcode = $this->barcode_codabar($code); 00342 break; 00343 } 00344 case 'CODE11': { // CODE 11 00345 $arrcode = $this->barcode_code11($code); 00346 break; 00347 } 00348 case 'PHARMA': { // PHARMACODE 00349 $arrcode = $this->barcode_pharmacode($code); 00350 break; 00351 } 00352 case 'PHARMA2T': { // PHARMACODE TWO-TRACKS 00353 $arrcode = $this->barcode_pharmacode2t($code); 00354 break; 00355 } 00356 default: { 00357 $this->barcode_array = false; 00358 $arrcode = false; 00359 break; 00360 } 00361 } 00362 $this->barcode_array = $arrcode; 00363 } 00364 00374 protected function barcode_code39($code, $extended=false, $checksum=false) { 00375 $chr['0'] = '111331311'; 00376 $chr['1'] = '311311113'; 00377 $chr['2'] = '113311113'; 00378 $chr['3'] = '313311111'; 00379 $chr['4'] = '111331113'; 00380 $chr['5'] = '311331111'; 00381 $chr['6'] = '113331111'; 00382 $chr['7'] = '111311313'; 00383 $chr['8'] = '311311311'; 00384 $chr['9'] = '113311311'; 00385 $chr['A'] = '311113113'; 00386 $chr['B'] = '113113113'; 00387 $chr['C'] = '313113111'; 00388 $chr['D'] = '111133113'; 00389 $chr['E'] = '311133111'; 00390 $chr['F'] = '113133111'; 00391 $chr['G'] = '111113313'; 00392 $chr['H'] = '311113311'; 00393 $chr['I'] = '113113311'; 00394 $chr['J'] = '111133311'; 00395 $chr['K'] = '311111133'; 00396 $chr['L'] = '113111133'; 00397 $chr['M'] = '313111131'; 00398 $chr['N'] = '111131133'; 00399 $chr['O'] = '311131131'; 00400 $chr['P'] = '113131131'; 00401 $chr['Q'] = '111111333'; 00402 $chr['R'] = '311111331'; 00403 $chr['S'] = '113111331'; 00404 $chr['T'] = '111131331'; 00405 $chr['U'] = '331111113'; 00406 $chr['V'] = '133111113'; 00407 $chr['W'] = '333111111'; 00408 $chr['X'] = '131131113'; 00409 $chr['Y'] = '331131111'; 00410 $chr['Z'] = '133131111'; 00411 $chr['-'] = '131111313'; 00412 $chr['.'] = '331111311'; 00413 $chr[' '] = '133111311'; 00414 $chr['$'] = '131313111'; 00415 $chr['/'] = '131311131'; 00416 $chr['+'] = '131113131'; 00417 $chr['%'] = '111313131'; 00418 $chr['*'] = '131131311'; 00419 $code = strtoupper($code); 00420 if ($extended) { 00421 // extended mode 00422 $code = $this->encode_code39_ext($code); 00423 } 00424 if ($code === false) { 00425 return false; 00426 } 00427 if ($checksum) { 00428 // checksum 00429 $code .= $this->checksum_code39($code); 00430 } 00431 // add start and stop codes 00432 $code = '*'.$code.'*'; 00433 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 00434 $k = 0; 00435 $clen = strlen($code); 00436 for ($i = 0; $i < $clen; ++$i) { 00437 $char = $code{$i}; 00438 if(!isset($chr[$char])) { 00439 // invalid character 00440 return false; 00441 } 00442 for ($j = 0; $j < 9; ++$j) { 00443 if (($j % 2) == 0) { 00444 $t = true; // bar 00445 } else { 00446 $t = false; // space 00447 } 00448 $w = $chr[$char]{$j}; 00449 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 00450 $bararray['maxw'] += $w; 00451 ++$k; 00452 } 00453 // intercharacter gap 00454 $bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0); 00455 $bararray['maxw'] += 1; 00456 ++$k; 00457 } 00458 return $bararray; 00459 } 00460 00467 protected function encode_code39_ext($code) { 00468 $encode = array( 00469 chr(0) => '%U', chr(1) => '$A', chr(2) => '$B', chr(3) => '$C', 00470 chr(4) => '$D', chr(5) => '$E', chr(6) => '$F', chr(7) => '$G', 00471 chr(8) => '$H', chr(9) => '$I', chr(10) => '$J', chr(11) => '£K', 00472 chr(12) => '$L', chr(13) => '$M', chr(14) => '$N', chr(15) => '$O', 00473 chr(16) => '$P', chr(17) => '$Q', chr(18) => '$R', chr(19) => '$S', 00474 chr(20) => '$T', chr(21) => '$U', chr(22) => '$V', chr(23) => '$W', 00475 chr(24) => '$X', chr(25) => '$Y', chr(26) => '$Z', chr(27) => '%A', 00476 chr(28) => '%B', chr(29) => '%C', chr(30) => '%D', chr(31) => '%E', 00477 chr(32) => ' ', chr(33) => '/A', chr(34) => '/B', chr(35) => '/C', 00478 chr(36) => '/D', chr(37) => '/E', chr(38) => '/F', chr(39) => '/G', 00479 chr(40) => '/H', chr(41) => '/I', chr(42) => '/J', chr(43) => '/K', 00480 chr(44) => '/L', chr(45) => '-', chr(46) => '.', chr(47) => '/O', 00481 chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3', 00482 chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7', 00483 chr(56) => '8', chr(57) => '9', chr(58) => '/Z', chr(59) => '%F', 00484 chr(60) => '%G', chr(61) => '%H', chr(62) => '%I', chr(63) => '%J', 00485 chr(64) => '%V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C', 00486 chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G', 00487 chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K', 00488 chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O', 00489 chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S', 00490 chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W', 00491 chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => '%K', 00492 chr(92) => '%L', chr(93) => '%M', chr(94) => '%N', chr(95) => '%O', 00493 chr(96) => '%W', chr(97) => '+A', chr(98) => '+B', chr(99) => '+C', 00494 chr(100) => '+D', chr(101) => '+E', chr(102) => '+F', chr(103) => '+G', 00495 chr(104) => '+H', chr(105) => '+I', chr(106) => '+J', chr(107) => '+K', 00496 chr(108) => '+L', chr(109) => '+M', chr(110) => '+N', chr(111) => '+O', 00497 chr(112) => '+P', chr(113) => '+Q', chr(114) => '+R', chr(115) => '+S', 00498 chr(116) => '+T', chr(117) => '+U', chr(118) => '+V', chr(119) => '+W', 00499 chr(120) => '+X', chr(121) => '+Y', chr(122) => '+Z', chr(123) => '%P', 00500 chr(124) => '%Q', chr(125) => '%R', chr(126) => '%S', chr(127) => '%T'); 00501 $code_ext = ''; 00502 $clen = strlen($code); 00503 for ($i = 0 ; $i < $clen; ++$i) { 00504 if (ord($code{$i}) > 127) { 00505 return false; 00506 } 00507 $code_ext .= $encode[$code{$i}]; 00508 } 00509 return $code_ext; 00510 } 00511 00518 protected function checksum_code39($code) { 00519 $chars = array( 00520 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 00521 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 00522 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 00523 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%'); 00524 $sum = 0; 00525 $clen = strlen($code); 00526 for ($i = 0 ; $i < $clen; ++$i) { 00527 $k = array_keys($chars, $code{$i}); 00528 $sum += $k[0]; 00529 } 00530 $j = ($sum % 43); 00531 return $chars[$j]; 00532 } 00533 00541 protected function barcode_code93($code) { 00542 $chr[48] = '131112'; // 0 00543 $chr[49] = '111213'; // 1 00544 $chr[50] = '111312'; // 2 00545 $chr[51] = '111411'; // 3 00546 $chr[52] = '121113'; // 4 00547 $chr[53] = '121212'; // 5 00548 $chr[54] = '121311'; // 6 00549 $chr[55] = '111114'; // 7 00550 $chr[56] = '131211'; // 8 00551 $chr[57] = '141111'; // 9 00552 $chr[65] = '211113'; // A 00553 $chr[66] = '211212'; // B 00554 $chr[67] = '211311'; // C 00555 $chr[68] = '221112'; // D 00556 $chr[69] = '221211'; // E 00557 $chr[70] = '231111'; // F 00558 $chr[71] = '112113'; // G 00559 $chr[72] = '112212'; // H 00560 $chr[73] = '112311'; // I 00561 $chr[74] = '122112'; // J 00562 $chr[75] = '132111'; // K 00563 $chr[76] = '111123'; // L 00564 $chr[77] = '111222'; // M 00565 $chr[78] = '111321'; // N 00566 $chr[79] = '121122'; // O 00567 $chr[80] = '131121'; // P 00568 $chr[81] = '212112'; // Q 00569 $chr[82] = '212211'; // R 00570 $chr[83] = '211122'; // S 00571 $chr[84] = '211221'; // T 00572 $chr[85] = '221121'; // U 00573 $chr[86] = '222111'; // V 00574 $chr[87] = '112122'; // W 00575 $chr[88] = '112221'; // X 00576 $chr[89] = '122121'; // Y 00577 $chr[90] = '123111'; // Z 00578 $chr[45] = '121131'; // - 00579 $chr[46] = '311112'; // . 00580 $chr[32] = '311211'; // 00581 $chr[36] = '321111'; // $ 00582 $chr[47] = '112131'; // / 00583 $chr[43] = '113121'; // + 00584 $chr[37] = '211131'; // % 00585 $chr[128] = '121221'; // ($) 00586 $chr[129] = '311121'; // (/) 00587 $chr[130] = '122211'; // (+) 00588 $chr[131] = '312111'; // (%) 00589 $chr[42] = '111141'; // start-stop 00590 $code = strtoupper($code); 00591 $encode = array( 00592 chr(0) => chr(131).'U', chr(1) => chr(128).'A', chr(2) => chr(128).'B', chr(3) => chr(128).'C', 00593 chr(4) => chr(128).'D', chr(5) => chr(128).'E', chr(6) => chr(128).'F', chr(7) => chr(128).'G', 00594 chr(8) => chr(128).'H', chr(9) => chr(128).'I', chr(10) => chr(128).'J', chr(11) => '£K', 00595 chr(12) => chr(128).'L', chr(13) => chr(128).'M', chr(14) => chr(128).'N', chr(15) => chr(128).'O', 00596 chr(16) => chr(128).'P', chr(17) => chr(128).'Q', chr(18) => chr(128).'R', chr(19) => chr(128).'S', 00597 chr(20) => chr(128).'T', chr(21) => chr(128).'U', chr(22) => chr(128).'V', chr(23) => chr(128).'W', 00598 chr(24) => chr(128).'X', chr(25) => chr(128).'Y', chr(26) => chr(128).'Z', chr(27) => chr(131).'A', 00599 chr(28) => chr(131).'B', chr(29) => chr(131).'C', chr(30) => chr(131).'D', chr(31) => chr(131).'E', 00600 chr(32) => ' ', chr(33) => chr(129).'A', chr(34) => chr(129).'B', chr(35) => chr(129).'C', 00601 chr(36) => chr(129).'D', chr(37) => chr(129).'E', chr(38) => chr(129).'F', chr(39) => chr(129).'G', 00602 chr(40) => chr(129).'H', chr(41) => chr(129).'I', chr(42) => chr(129).'J', chr(43) => chr(129).'K', 00603 chr(44) => chr(129).'L', chr(45) => '-', chr(46) => '.', chr(47) => chr(129).'O', 00604 chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3', 00605 chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7', 00606 chr(56) => '8', chr(57) => '9', chr(58) => chr(129).'Z', chr(59) => chr(131).'F', 00607 chr(60) => chr(131).'G', chr(61) => chr(131).'H', chr(62) => chr(131).'I', chr(63) => chr(131).'J', 00608 chr(64) => chr(131).'V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C', 00609 chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G', 00610 chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K', 00611 chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O', 00612 chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S', 00613 chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W', 00614 chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => chr(131).'K', 00615 chr(92) => chr(131).'L', chr(93) => chr(131).'M', chr(94) => chr(131).'N', chr(95) => chr(131).'O', 00616 chr(96) => chr(131).'W', chr(97) => chr(130).'A', chr(98) => chr(130).'B', chr(99) => chr(130).'C', 00617 chr(100) => chr(130).'D', chr(101) => chr(130).'E', chr(102) => chr(130).'F', chr(103) => chr(130).'G', 00618 chr(104) => chr(130).'H', chr(105) => chr(130).'I', chr(106) => chr(130).'J', chr(107) => chr(130).'K', 00619 chr(108) => chr(130).'L', chr(109) => chr(130).'M', chr(110) => chr(130).'N', chr(111) => chr(130).'O', 00620 chr(112) => chr(130).'P', chr(113) => chr(130).'Q', chr(114) => chr(130).'R', chr(115) => chr(130).'S', 00621 chr(116) => chr(130).'T', chr(117) => chr(130).'U', chr(118) => chr(130).'V', chr(119) => chr(130).'W', 00622 chr(120) => chr(130).'X', chr(121) => chr(130).'Y', chr(122) => chr(130).'Z', chr(123) => chr(131).'P', 00623 chr(124) => chr(131).'Q', chr(125) => chr(131).'R', chr(126) => chr(131).'S', chr(127) => chr(131).'T'); 00624 $code_ext = ''; 00625 $clen = strlen($code); 00626 for ($i = 0 ; $i < $clen; ++$i) { 00627 if (ord($code{$i}) > 127) { 00628 return false; 00629 } 00630 $code_ext .= $encode[$code{$i}]; 00631 } 00632 // checksum 00633 $code_ext .= $this->checksum_code93($code_ext); 00634 // add start and stop codes 00635 $code = '*'.$code_ext.'*'; 00636 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 00637 $k = 0; 00638 $clen = strlen($code); 00639 for ($i = 0; $i < $clen; ++$i) { 00640 $char = ord($code{$i}); 00641 if(!isset($chr[$char])) { 00642 // invalid character 00643 return false; 00644 } 00645 for ($j = 0; $j < 6; ++$j) { 00646 if (($j % 2) == 0) { 00647 $t = true; // bar 00648 } else { 00649 $t = false; // space 00650 } 00651 $w = $chr[$char]{$j}; 00652 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 00653 $bararray['maxw'] += $w; 00654 ++$k; 00655 } 00656 } 00657 $bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0); 00658 $bararray['maxw'] += 1; 00659 ++$k; 00660 return $bararray; 00661 } 00662 00669 protected function checksum_code93($code) { 00670 $chars = array( 00671 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 00672 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 00673 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 00674 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%', 00675 '<', '=', '>', '?'); 00676 // translate special characters 00677 $code = strtr($code, chr(128).chr(131).chr(129).chr(130), '<=>?'); 00678 $len = strlen($code); 00679 // calculate check digit C 00680 $p = 1; 00681 $check = 0; 00682 for ($i = ($len - 1); $i >= 0; --$i) { 00683 $k = array_keys($chars, $code{$i}); 00684 $check += ($k[0] * $p); 00685 ++$p; 00686 if ($p > 20) { 00687 $p = 1; 00688 } 00689 } 00690 $check %= 47; 00691 $c = $chars[$check]; 00692 $code .= $c; 00693 // calculate check digit K 00694 $p = 1; 00695 $check = 0; 00696 for ($i = $len; $i >= 0; --$i) { 00697 $k = array_keys($chars, $code{$i}); 00698 $check += ($k[0] * $p); 00699 ++$p; 00700 if ($p > 15) { 00701 $p = 1; 00702 } 00703 } 00704 $check %= 47; 00705 $k = $chars[$check]; 00706 $checksum = $c.$k; 00707 // resto respecial characters 00708 $checksum = strtr($checksum, '<=>?', chr(128).chr(131).chr(129).chr(130)); 00709 return $checksum; 00710 } 00711 00718 protected function checksum_s25($code) { 00719 $len = strlen($code); 00720 $sum = 0; 00721 for ($i = 0; $i < $len; $i+=2) { 00722 $sum += $code{$i}; 00723 } 00724 $sum *= 3; 00725 for ($i = 1; $i < $len; $i+=2) { 00726 $sum += ($code{$i}); 00727 } 00728 $r = $sum % 10; 00729 if($r > 0) { 00730 $r = (10 - $r); 00731 } 00732 return $r; 00733 } 00734 00744 protected function barcode_msi($code, $checksum=false) { 00745 $chr['0'] = '100100100100'; 00746 $chr['1'] = '100100100110'; 00747 $chr['2'] = '100100110100'; 00748 $chr['3'] = '100100110110'; 00749 $chr['4'] = '100110100100'; 00750 $chr['5'] = '100110100110'; 00751 $chr['6'] = '100110110100'; 00752 $chr['7'] = '100110110110'; 00753 $chr['8'] = '110100100100'; 00754 $chr['9'] = '110100100110'; 00755 $chr['A'] = '110100110100'; 00756 $chr['B'] = '110100110110'; 00757 $chr['C'] = '110110100100'; 00758 $chr['D'] = '110110100110'; 00759 $chr['E'] = '110110110100'; 00760 $chr['F'] = '110110110110'; 00761 if ($checksum) { 00762 // add checksum 00763 $clen = strlen($code); 00764 $p = 2; 00765 $check = 0; 00766 for ($i = ($clen - 1); $i >= 0; --$i) { 00767 $check += (hexdec($code{$i}) * $p); 00768 ++$p; 00769 if ($p > 7) { 00770 $p = 2; 00771 } 00772 } 00773 $check %= 11; 00774 if ($check > 0) { 00775 $check = 11 - $check; 00776 } 00777 $code .= $check; 00778 } 00779 $seq = '110'; // left guard 00780 $clen = strlen($code); 00781 for ($i = 0; $i < $clen; ++$i) { 00782 $digit = $code{$i}; 00783 if (!isset($chr[$digit])) { 00784 // invalid character 00785 return false; 00786 } 00787 $seq .= $chr[$digit]; 00788 } 00789 $seq .= '1001'; // right guard 00790 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 00791 return $this->binseq_to_array($seq, $bararray); 00792 } 00793 00803 protected function barcode_s25($code, $checksum=false) { 00804 $chr['0'] = '10101110111010'; 00805 $chr['1'] = '11101010101110'; 00806 $chr['2'] = '10111010101110'; 00807 $chr['3'] = '11101110101010'; 00808 $chr['4'] = '10101110101110'; 00809 $chr['5'] = '11101011101010'; 00810 $chr['6'] = '10111011101010'; 00811 $chr['7'] = '10101011101110'; 00812 $chr['8'] = '10101110111010'; 00813 $chr['9'] = '10111010111010'; 00814 if ($checksum) { 00815 // add checksum 00816 $code .= $this->checksum_s25($code); 00817 } 00818 if((strlen($code) % 2) != 0) { 00819 // add leading zero if code-length is odd 00820 $code = '0'.$code; 00821 } 00822 $seq = '11011010'; 00823 $clen = strlen($code); 00824 for ($i = 0; $i < $clen; ++$i) { 00825 $digit = $code{$i}; 00826 if (!isset($chr[$digit])) { 00827 // invalid character 00828 return false; 00829 } 00830 $seq .= $chr[$digit]; 00831 } 00832 $seq .= '1101011'; 00833 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 00834 return $this->binseq_to_array($seq, $bararray); 00835 } 00836 00845 protected function binseq_to_array($seq, $bararray) { 00846 $len = strlen($seq); 00847 $w = 0; 00848 $k = 0; 00849 for ($i = 0; $i < $len; ++$i) { 00850 $w += 1; 00851 if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq{$i} != $seq{($i+1)}))) { 00852 if ($seq{$i} == '1') { 00853 $t = true; // bar 00854 } else { 00855 $t = false; // space 00856 } 00857 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 00858 $bararray['maxw'] += $w; 00859 ++$k; 00860 $w = 0; 00861 } 00862 } 00863 return $bararray; 00864 } 00865 00875 protected function barcode_i25($code, $checksum=false) { 00876 $chr['0'] = '11221'; 00877 $chr['1'] = '21112'; 00878 $chr['2'] = '12112'; 00879 $chr['3'] = '22111'; 00880 $chr['4'] = '11212'; 00881 $chr['5'] = '21211'; 00882 $chr['6'] = '12211'; 00883 $chr['7'] = '11122'; 00884 $chr['8'] = '21121'; 00885 $chr['9'] = '12121'; 00886 $chr['A'] = '11'; 00887 $chr['Z'] = '21'; 00888 if ($checksum) { 00889 // add checksum 00890 $code .= $this->checksum_s25($code); 00891 } 00892 if((strlen($code) % 2) != 0) { 00893 // add leading zero if code-length is odd 00894 $code = '0'.$code; 00895 } 00896 // add start and stop codes 00897 $code = 'AA'.strtolower($code).'ZA'; 00898 00899 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 00900 $k = 0; 00901 $clen = strlen($code); 00902 for ($i = 0; $i < $clen; $i = ($i + 2)) { 00903 $char_bar = $code{$i}; 00904 $char_space = $code{$i+1}; 00905 if((!isset($chr[$char_bar])) OR (!isset($chr[$char_space]))) { 00906 // invalid character 00907 return false; 00908 } 00909 // create a bar-space sequence 00910 $seq = ''; 00911 $chrlen = strlen($chr[$char_bar]); 00912 for ($s = 0; $s < $chrlen; $s++){ 00913 $seq .= $chr[$char_bar]{$s} . $chr[$char_space]{$s}; 00914 } 00915 $seqlen = strlen($seq); 00916 for ($j = 0; $j < $seqlen; ++$j) { 00917 if (($j % 2) == 0) { 00918 $t = true; // bar 00919 } else { 00920 $t = false; // space 00921 } 00922 $w = $seq{$j}; 00923 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 00924 $bararray['maxw'] += $w; 00925 ++$k; 00926 } 00927 } 00928 return $bararray; 00929 } 00930 00939 protected function barcode_c128($code, $type='') { 00940 $chr = array( 00941 '212222', /* 00 */ 00942 '222122', /* 01 */ 00943 '222221', /* 02 */ 00944 '121223', /* 03 */ 00945 '121322', /* 04 */ 00946 '131222', /* 05 */ 00947 '122213', /* 06 */ 00948 '122312', /* 07 */ 00949 '132212', /* 08 */ 00950 '221213', /* 09 */ 00951 '221312', /* 10 */ 00952 '231212', /* 11 */ 00953 '112232', /* 12 */ 00954 '122132', /* 13 */ 00955 '122231', /* 14 */ 00956 '113222', /* 15 */ 00957 '123122', /* 16 */ 00958 '123221', /* 17 */ 00959 '223211', /* 18 */ 00960 '221132', /* 19 */ 00961 '221231', /* 20 */ 00962 '213212', /* 21 */ 00963 '223112', /* 22 */ 00964 '312131', /* 23 */ 00965 '311222', /* 24 */ 00966 '321122', /* 25 */ 00967 '321221', /* 26 */ 00968 '312212', /* 27 */ 00969 '322112', /* 28 */ 00970 '322211', /* 29 */ 00971 '212123', /* 30 */ 00972 '212321', /* 31 */ 00973 '232121', /* 32 */ 00974 '111323', /* 33 */ 00975 '131123', /* 34 */ 00976 '131321', /* 35 */ 00977 '112313', /* 36 */ 00978 '132113', /* 37 */ 00979 '132311', /* 38 */ 00980 '211313', /* 39 */ 00981 '231113', /* 40 */ 00982 '231311', /* 41 */ 00983 '112133', /* 42 */ 00984 '112331', /* 43 */ 00985 '132131', /* 44 */ 00986 '113123', /* 45 */ 00987 '113321', /* 46 */ 00988 '133121', /* 47 */ 00989 '313121', /* 48 */ 00990 '211331', /* 49 */ 00991 '231131', /* 50 */ 00992 '213113', /* 51 */ 00993 '213311', /* 52 */ 00994 '213131', /* 53 */ 00995 '311123', /* 54 */ 00996 '311321', /* 55 */ 00997 '331121', /* 56 */ 00998 '312113', /* 57 */ 00999 '312311', /* 58 */ 01000 '332111', /* 59 */ 01001 '314111', /* 60 */ 01002 '221411', /* 61 */ 01003 '431111', /* 62 */ 01004 '111224', /* 63 */ 01005 '111422', /* 64 */ 01006 '121124', /* 65 */ 01007 '121421', /* 66 */ 01008 '141122', /* 67 */ 01009 '141221', /* 68 */ 01010 '112214', /* 69 */ 01011 '112412', /* 70 */ 01012 '122114', /* 71 */ 01013 '122411', /* 72 */ 01014 '142112', /* 73 */ 01015 '142211', /* 74 */ 01016 '241211', /* 75 */ 01017 '221114', /* 76 */ 01018 '413111', /* 77 */ 01019 '241112', /* 78 */ 01020 '134111', /* 79 */ 01021 '111242', /* 80 */ 01022 '121142', /* 81 */ 01023 '121241', /* 82 */ 01024 '114212', /* 83 */ 01025 '124112', /* 84 */ 01026 '124211', /* 85 */ 01027 '411212', /* 86 */ 01028 '421112', /* 87 */ 01029 '421211', /* 88 */ 01030 '212141', /* 89 */ 01031 '214121', /* 90 */ 01032 '412121', /* 91 */ 01033 '111143', /* 92 */ 01034 '111341', /* 93 */ 01035 '131141', /* 94 */ 01036 '114113', /* 95 */ 01037 '114311', /* 96 */ 01038 '411113', /* 97 */ 01039 '411311', /* 98 */ 01040 '113141', /* 99 */ 01041 '114131', /* 100 */ 01042 '311141', /* 101 */ 01043 '411131', /* 102 */ 01044 '211412', /* 103 START A */ 01045 '211214', /* 104 START B */ 01046 '211232', /* 105 START C */ 01047 '233111', /* STOP */ 01048 '200000' /* END */ 01049 ); 01050 // ASCII characters for code A (ASCII 00 - 95) 01051 $keys_a = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'; 01052 $keys_a .= chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).chr(9); 01053 $keys_a .= chr(10).chr(11).chr(12).chr(13).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19); 01054 $keys_a .= chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29); 01055 $keys_a .= chr(30).chr(31); 01056 // ASCII characters for code B (ASCII 32 - 127) 01057 $keys_b = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127); 01058 // special codes 01059 $fnc_a = array(241 => 102, 242 => 97, 243 => 96, 244 => 101); 01060 $fnc_b = array(241 => 102, 242 => 97, 243 => 96, 244 => 100); 01061 // array of symbols 01062 $code_data = array(); 01063 // lenght of the code 01064 $len = strlen($code); 01065 switch(strtoupper($type)) { 01066 case 'A': { // MODE A 01067 $startid = 103; 01068 for ($i = 0; $i < $len; ++$i) { 01069 $char = $code{$i}; 01070 $char_id = ord($char); 01071 if (($char_id >= 241) AND ($char_id <= 244)) { 01072 $code_data[] = $fnc_a[$char_id]; 01073 } elseif (($char_id >= 0) AND ($char_id <= 95)) { 01074 $code_data[] = strpos($keys_a, $char); 01075 } else { 01076 return false; 01077 } 01078 } 01079 break; 01080 } 01081 case 'B': { // MODE B 01082 $startid = 104; 01083 for ($i = 0; $i < $len; ++$i) { 01084 $char = $code{$i}; 01085 $char_id = ord($char); 01086 if (($char_id >= 241) AND ($char_id <= 244)) { 01087 $code_data[] = $fnc_b[$char_id]; 01088 } elseif (($char_id >= 32) AND ($char_id <= 127)) { 01089 $code_data[] = strpos($keys_b, $char); 01090 } else { 01091 return false; 01092 } 01093 } 01094 break; 01095 } 01096 case 'C': { // MODE C 01097 $startid = 105; 01098 if (ord($code{0}) == 241) { 01099 $code_data[] = 102; 01100 $code = substr($code, 1); 01101 --$len; 01102 } 01103 if (($len % 2) != 0) { 01104 // the length must be even 01105 return false; 01106 } 01107 for ($i = 0; $i < $len; $i+=2) { 01108 $chrnum = $code{$i}.$code{$i+1}; 01109 if (preg_match('/([0-9]{2})/', $chrnum) > 0) { 01110 $code_data[] = intval($chrnum); 01111 } else { 01112 return false; 01113 } 01114 } 01115 break; 01116 } 01117 default: { // MODE AUTO 01118 // split code into sequences 01119 $sequence = array(); 01120 // get numeric sequences (if any) 01121 $numseq = array(); 01122 preg_match_all('/([0-9]{4,})/', $code, $numseq, PREG_OFFSET_CAPTURE); 01123 if (isset($numseq[1]) AND !empty($numseq[1])) { 01124 $end_offset = 0; 01125 foreach ($numseq[1] as $val) { 01126 $offset = $val[1]; 01127 if ($offset > $end_offset) { 01128 // non numeric sequence 01129 $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset, ($offset - $end_offset)))); 01130 } 01131 // numeric sequence 01132 $slen = strlen($val[0]); 01133 if (($slen % 2) != 0) { 01134 // the length must be even 01135 --$slen; 01136 } 01137 $sequence[] = array('C', substr($code, $offset, $slen), $slen); 01138 $end_offset = $offset + $slen; 01139 } 01140 if ($end_offset < $len) { 01141 $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset))); 01142 } 01143 } else { 01144 // text code (non C mode) 01145 $sequence = array_merge($sequence, $this->get128ABsequence($code)); 01146 } 01147 // process the sequence 01148 foreach ($sequence as $key => $seq) { 01149 switch($seq[0]) { 01150 case 'A': { 01151 if ($key == 0) { 01152 $startid = 103; 01153 } elseif ($sequence[($key - 1)][0] != 'A') { 01154 if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'B') AND (!isset($sequence[($key - 1)][3]))) { 01155 // single character shift 01156 $code_data[] = 98; 01157 // mark shift 01158 $sequence[$key][3] = true; 01159 } elseif (!isset($sequence[($key - 1)][3])) { 01160 $code_data[] = 101; 01161 } 01162 } 01163 for ($i = 0; $i < $seq[2]; ++$i) { 01164 $char = $seq[1]{$i}; 01165 $char_id = ord($char); 01166 if (($char_id >= 241) AND ($char_id <= 244)) { 01167 $code_data[] = $fnc_a[$char_id]; 01168 } else { 01169 $code_data[] = strpos($keys_a, $char); 01170 } 01171 } 01172 break; 01173 } 01174 case 'B': { 01175 if ($key == 0) { 01176 $tmpchr = ord($seq[1]{0}); 01177 if (($seq[2] == 1) AND ($tmpchr >= 241) AND ($tmpchr <= 244) AND isset($sequence[($key + 1)]) AND ($sequence[($key + 1)][0] != 'B')) { 01178 switch ($sequence[($key + 1)][0]) { 01179 case 'A': { 01180 $startid = 103; 01181 $sequence[$key][0] = 'A'; 01182 $code_data[] = $fnc_a[$tmpchr]; 01183 break; 01184 } 01185 case 'C': { 01186 $startid = 105; 01187 $sequence[$key][0] = 'C'; 01188 $code_data[] = $fnc_a[$tmpchr]; 01189 break; 01190 } 01191 } 01192 break; 01193 } else { 01194 $startid = 104; 01195 } 01196 } elseif ($sequence[($key - 1)][0] != 'B') { 01197 if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'A') AND (!isset($sequence[($key - 1)][3]))) { 01198 // single character shift 01199 $code_data[] = 98; 01200 // mark shift 01201 $sequence[$key][3] = true; 01202 } elseif (!isset($sequence[($key - 1)][3])) { 01203 $code_data[] = 100; 01204 } 01205 } 01206 for ($i = 0; $i < $seq[2]; ++$i) { 01207 $char = $seq[1]{$i}; 01208 $char_id = ord($char); 01209 if (($char_id >= 241) AND ($char_id <= 244)) { 01210 $code_data[] = $fnc_b[$char_id]; 01211 } else { 01212 $code_data[] = strpos($keys_b, $char); 01213 } 01214 } 01215 break; 01216 } 01217 case 'C': { 01218 if ($key == 0) { 01219 $startid = 105; 01220 } elseif ($sequence[($key - 1)][0] != 'C') { 01221 $code_data[] = 99; 01222 } 01223 for ($i = 0; $i < $seq[2]; $i+=2) { 01224 $chrnum = $seq[1]{$i}.$seq[1]{$i+1}; 01225 $code_data[] = intval($chrnum); 01226 } 01227 break; 01228 } 01229 } 01230 } 01231 } 01232 } 01233 // calculate check character 01234 $sum = $startid; 01235 foreach ($code_data as $key => $val) { 01236 $sum += ($val * ($key + 1)); 01237 } 01238 // add check character 01239 $code_data[] = ($sum % 103); 01240 // add stop sequence 01241 $code_data[] = 106; 01242 $code_data[] = 107; 01243 // add start code at the beginning 01244 array_unshift($code_data, $startid); 01245 // build barcode array 01246 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01247 foreach ($code_data as $val) { 01248 $seq = $chr[$val]; 01249 for ($j = 0; $j < 6; ++$j) { 01250 if (($j % 2) == 0) { 01251 $t = true; // bar 01252 } else { 01253 $t = false; // space 01254 } 01255 $w = $seq{$j}; 01256 $bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 01257 $bararray['maxw'] += $w; 01258 } 01259 } 01260 return $bararray; 01261 } 01262 01269 protected function get128ABsequence($code) { 01270 $len = strlen($code); 01271 $sequence = array(); 01272 // get A sequences (if any) 01273 $numseq = array(); 01274 preg_match_all('/([\0-\31])/', $code, $numseq, PREG_OFFSET_CAPTURE); 01275 if (isset($numseq[1]) AND !empty($numseq[1])) { 01276 $end_offset = 0; 01277 foreach ($numseq[1] as $val) { 01278 $offset = $val[1]; 01279 if ($offset > $end_offset) { 01280 // B sequence 01281 $sequence[] = array('B', substr($code, $end_offset, ($offset - $end_offset)), ($offset - $end_offset)); 01282 } 01283 // A sequence 01284 $slen = strlen($val[0]); 01285 $sequence[] = array('A', substr($code, $offset, $slen), $slen); 01286 $end_offset = $offset + $slen; 01287 } 01288 if ($end_offset < $len) { 01289 $sequence[] = array('B', substr($code, $end_offset), ($len - $end_offset)); 01290 } 01291 } else { 01292 // only B sequence 01293 $sequence[] = array('B', $code, $len); 01294 } 01295 return $sequence; 01296 } 01297 01308 protected function barcode_eanupc($code, $len=13) { 01309 $upce = false; 01310 if ($len == 6) { 01311 $len = 12; // UPC-A 01312 $upce = true; // UPC-E mode 01313 } 01314 $data_len = $len - 1; 01315 //Padding 01316 $code = str_pad($code, $data_len, '0', STR_PAD_LEFT); 01317 $code_len = strlen($code); 01318 // calculate check digit 01319 $sum_a = 0; 01320 for ($i = 1; $i < $data_len; $i+=2) { 01321 $sum_a += $code{$i}; 01322 } 01323 if ($len > 12) { 01324 $sum_a *= 3; 01325 } 01326 $sum_b = 0; 01327 for ($i = 0; $i < $data_len; $i+=2) { 01328 $sum_b += ($code{$i}); 01329 } 01330 if ($len < 13) { 01331 $sum_b *= 3; 01332 } 01333 $r = ($sum_a + $sum_b) % 10; 01334 if($r > 0) { 01335 $r = (10 - $r); 01336 } 01337 if ($code_len == $data_len) { 01338 // add check digit 01339 $code .= $r; 01340 } elseif ($r !== intval($code{$data_len})) { 01341 // wrong checkdigit 01342 return false; 01343 } 01344 if ($len == 12) { 01345 // UPC-A 01346 $code = '0'.$code; 01347 ++$len; 01348 } 01349 if ($upce) { 01350 // convert UPC-A to UPC-E 01351 $tmp = substr($code, 4, 3); 01352 if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) { 01353 // manufacturer code ends in 000, 100, or 200 01354 $upce_code = substr($code, 2, 2).substr($code, 9, 3).substr($code, 4, 1); 01355 } else { 01356 $tmp = substr($code, 5, 2); 01357 if ($tmp == '00') { 01358 // manufacturer code ends in 00 01359 $upce_code = substr($code, 2, 3).substr($code, 10, 2).'3'; 01360 } else { 01361 $tmp = substr($code, 6, 1); 01362 if ($tmp == '0') { 01363 // manufacturer code ends in 0 01364 $upce_code = substr($code, 2, 4).substr($code, 11, 1).'4'; 01365 } else { 01366 // manufacturer code does not end in zero 01367 $upce_code = substr($code, 2, 5).substr($code, 11, 1); 01368 } 01369 } 01370 } 01371 } 01372 //Convert digits to bars 01373 $codes = array( 01374 'A'=>array( // left odd parity 01375 '0'=>'0001101', 01376 '1'=>'0011001', 01377 '2'=>'0010011', 01378 '3'=>'0111101', 01379 '4'=>'0100011', 01380 '5'=>'0110001', 01381 '6'=>'0101111', 01382 '7'=>'0111011', 01383 '8'=>'0110111', 01384 '9'=>'0001011'), 01385 'B'=>array( // left even parity 01386 '0'=>'0100111', 01387 '1'=>'0110011', 01388 '2'=>'0011011', 01389 '3'=>'0100001', 01390 '4'=>'0011101', 01391 '5'=>'0111001', 01392 '6'=>'0000101', 01393 '7'=>'0010001', 01394 '8'=>'0001001', 01395 '9'=>'0010111'), 01396 'C'=>array( // right 01397 '0'=>'1110010', 01398 '1'=>'1100110', 01399 '2'=>'1101100', 01400 '3'=>'1000010', 01401 '4'=>'1011100', 01402 '5'=>'1001110', 01403 '6'=>'1010000', 01404 '7'=>'1000100', 01405 '8'=>'1001000', 01406 '9'=>'1110100') 01407 ); 01408 $parities = array( 01409 '0'=>array('A','A','A','A','A','A'), 01410 '1'=>array('A','A','B','A','B','B'), 01411 '2'=>array('A','A','B','B','A','B'), 01412 '3'=>array('A','A','B','B','B','A'), 01413 '4'=>array('A','B','A','A','B','B'), 01414 '5'=>array('A','B','B','A','A','B'), 01415 '6'=>array('A','B','B','B','A','A'), 01416 '7'=>array('A','B','A','B','A','B'), 01417 '8'=>array('A','B','A','B','B','A'), 01418 '9'=>array('A','B','B','A','B','A') 01419 ); 01420 $upce_parities = array(); 01421 $upce_parities[0] = array( 01422 '0'=>array('B','B','B','A','A','A'), 01423 '1'=>array('B','B','A','B','A','A'), 01424 '2'=>array('B','B','A','A','B','A'), 01425 '3'=>array('B','B','A','A','A','B'), 01426 '4'=>array('B','A','B','B','A','A'), 01427 '5'=>array('B','A','A','B','B','A'), 01428 '6'=>array('B','A','A','A','B','B'), 01429 '7'=>array('B','A','B','A','B','A'), 01430 '8'=>array('B','A','B','A','A','B'), 01431 '9'=>array('B','A','A','B','A','B') 01432 ); 01433 $upce_parities[1] = array( 01434 '0'=>array('A','A','A','B','B','B'), 01435 '1'=>array('A','A','B','A','B','B'), 01436 '2'=>array('A','A','B','B','A','B'), 01437 '3'=>array('A','A','B','B','B','A'), 01438 '4'=>array('A','B','A','A','B','B'), 01439 '5'=>array('A','B','B','A','A','B'), 01440 '6'=>array('A','B','B','B','A','A'), 01441 '7'=>array('A','B','A','B','A','B'), 01442 '8'=>array('A','B','A','B','B','A'), 01443 '9'=>array('A','B','B','A','B','A') 01444 ); 01445 $k = 0; 01446 $seq = '101'; // left guard bar 01447 if ($upce) { 01448 $bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01449 $p = $upce_parities[$code{1}][$r]; 01450 for ($i = 0; $i < 6; ++$i) { 01451 $seq .= $codes[$p[$i]][$upce_code{$i}]; 01452 } 01453 $seq .= '010101'; // right guard bar 01454 } else { 01455 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01456 $half_len = ceil($len / 2); 01457 if ($len == 8) { 01458 for ($i = 0; $i < $half_len; ++$i) { 01459 $seq .= $codes['A'][$code{$i}]; 01460 } 01461 } else { 01462 $p = $parities[$code{0}]; 01463 for ($i = 1; $i < $half_len; ++$i) { 01464 $seq .= $codes[$p[$i-1]][$code{$i}]; 01465 } 01466 } 01467 $seq .= '01010'; // center guard bar 01468 for ($i = $half_len; $i < $len; ++$i) { 01469 $seq .= $codes['C'][$code{$i}]; 01470 } 01471 $seq .= '101'; // right guard bar 01472 } 01473 $clen = strlen($seq); 01474 $w = 0; 01475 for ($i = 0; $i < $clen; ++$i) { 01476 $w += 1; 01477 if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq{$i} != $seq{($i+1)}))) { 01478 if ($seq{$i} == '1') { 01479 $t = true; // bar 01480 } else { 01481 $t = false; // space 01482 } 01483 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 01484 $bararray['maxw'] += $w; 01485 ++$k; 01486 $w = 0; 01487 } 01488 } 01489 return $bararray; 01490 } 01491 01501 protected function barcode_eanext($code, $len=5) { 01502 //Padding 01503 $code = str_pad($code, $len, '0', STR_PAD_LEFT); 01504 // calculate check digit 01505 if ($len == 2) { 01506 $r = $code % 4; 01507 } elseif ($len == 5) { 01508 $r = (3 * ($code{0} + $code{2} + $code{4})) + (9 * ($code{1} + $code{3})); 01509 $r %= 10; 01510 } else { 01511 return false; 01512 } 01513 //Convert digits to bars 01514 $codes = array( 01515 'A'=>array( // left odd parity 01516 '0'=>'0001101', 01517 '1'=>'0011001', 01518 '2'=>'0010011', 01519 '3'=>'0111101', 01520 '4'=>'0100011', 01521 '5'=>'0110001', 01522 '6'=>'0101111', 01523 '7'=>'0111011', 01524 '8'=>'0110111', 01525 '9'=>'0001011'), 01526 'B'=>array( // left even parity 01527 '0'=>'0100111', 01528 '1'=>'0110011', 01529 '2'=>'0011011', 01530 '3'=>'0100001', 01531 '4'=>'0011101', 01532 '5'=>'0111001', 01533 '6'=>'0000101', 01534 '7'=>'0010001', 01535 '8'=>'0001001', 01536 '9'=>'0010111') 01537 ); 01538 $parities = array(); 01539 $parities[2] = array( 01540 '0'=>array('A','A'), 01541 '1'=>array('A','B'), 01542 '2'=>array('B','A'), 01543 '3'=>array('B','B') 01544 ); 01545 $parities[5] = array( 01546 '0'=>array('B','B','A','A','A'), 01547 '1'=>array('B','A','B','A','A'), 01548 '2'=>array('B','A','A','B','A'), 01549 '3'=>array('B','A','A','A','B'), 01550 '4'=>array('A','B','B','A','A'), 01551 '5'=>array('A','A','B','B','A'), 01552 '6'=>array('A','A','A','B','B'), 01553 '7'=>array('A','B','A','B','A'), 01554 '8'=>array('A','B','A','A','B'), 01555 '9'=>array('A','A','B','A','B') 01556 ); 01557 $p = $parities[$len][$r]; 01558 $seq = '1011'; // left guard bar 01559 $seq .= $codes[$p[0]][$code{0}]; 01560 for ($i = 1; $i < $len; ++$i) { 01561 $seq .= '01'; // separator 01562 $seq .= $codes[$p[$i]][$code{$i}]; 01563 } 01564 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01565 return $this->binseq_to_array($seq, $bararray); 01566 } 01567 01576 protected function barcode_postnet($code, $planet=false) { 01577 // bar lenght 01578 if ($planet) { 01579 $barlen = Array( 01580 0 => Array(1,1,2,2,2), 01581 1 => Array(2,2,2,1,1), 01582 2 => Array(2,2,1,2,1), 01583 3 => Array(2,2,1,1,2), 01584 4 => Array(2,1,2,2,1), 01585 5 => Array(2,1,2,1,2), 01586 6 => Array(2,1,1,2,2), 01587 7 => Array(1,2,2,2,1), 01588 8 => Array(1,2,2,1,2), 01589 9 => Array(1,2,1,2,2) 01590 ); 01591 } else { 01592 $barlen = Array( 01593 0 => Array(2,2,1,1,1), 01594 1 => Array(1,1,1,2,2), 01595 2 => Array(1,1,2,1,2), 01596 3 => Array(1,1,2,2,1), 01597 4 => Array(1,2,1,1,2), 01598 5 => Array(1,2,1,2,1), 01599 6 => Array(1,2,2,1,1), 01600 7 => Array(2,1,1,1,2), 01601 8 => Array(2,1,1,2,1), 01602 9 => Array(2,1,2,1,1) 01603 ); 01604 } 01605 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); 01606 $k = 0; 01607 $code = str_replace('-', '', $code); 01608 $code = str_replace(' ', '', $code); 01609 $len = strlen($code); 01610 // calculate checksum 01611 $sum = 0; 01612 for ($i = 0; $i < $len; ++$i) { 01613 $sum += intval($code{$i}); 01614 } 01615 $chkd = ($sum % 10); 01616 if($chkd > 0) { 01617 $chkd = (10 - $chkd); 01618 } 01619 $code .= $chkd; 01620 $len = strlen($code); 01621 // start bar 01622 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); 01623 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 01624 $bararray['maxw'] += 2; 01625 for ($i = 0; $i < $len; ++$i) { 01626 for ($j = 0; $j < 5; ++$j) { 01627 $h = $barlen[$code{$i}][$j]; 01628 $p = floor(1 / $h); 01629 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); 01630 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 01631 $bararray['maxw'] += 2; 01632 } 01633 } 01634 // end bar 01635 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); 01636 $bararray['maxw'] += 1; 01637 return $bararray; 01638 } 01639 01649 protected function barcode_rms4cc($code, $kix=false) { 01650 $notkix = !$kix; 01651 // bar mode 01652 // 1 = pos 1, length 2 01653 // 2 = pos 1, length 3 01654 // 3 = pos 2, length 1 01655 // 4 = pos 2, length 2 01656 $barmode = array( 01657 '0' => array(3,3,2,2), 01658 '1' => array(3,4,1,2), 01659 '2' => array(3,4,2,1), 01660 '3' => array(4,3,1,2), 01661 '4' => array(4,3,2,1), 01662 '5' => array(4,4,1,1), 01663 '6' => array(3,1,4,2), 01664 '7' => array(3,2,3,2), 01665 '8' => array(3,2,4,1), 01666 '9' => array(4,1,3,2), 01667 'A' => array(4,1,4,1), 01668 'B' => array(4,2,3,1), 01669 'C' => array(3,1,2,4), 01670 'D' => array(3,2,1,4), 01671 'E' => array(3,2,2,3), 01672 'F' => array(4,1,1,4), 01673 'G' => array(4,1,2,3), 01674 'H' => array(4,2,1,3), 01675 'I' => array(1,3,4,2), 01676 'J' => array(1,4,3,2), 01677 'K' => array(1,4,4,1), 01678 'L' => array(2,3,3,2), 01679 'M' => array(2,3,4,1), 01680 'N' => array(2,4,3,1), 01681 'O' => array(1,3,2,4), 01682 'P' => array(1,4,1,4), 01683 'Q' => array(1,4,2,3), 01684 'R' => array(2,3,1,4), 01685 'S' => array(2,3,2,3), 01686 'T' => array(2,4,1,3), 01687 'U' => array(1,1,4,4), 01688 'V' => array(1,2,3,4), 01689 'W' => array(1,2,4,3), 01690 'X' => array(2,1,3,4), 01691 'Y' => array(2,1,4,3), 01692 'Z' => array(2,2,3,3) 01693 ); 01694 $code = strtoupper($code); 01695 $len = strlen($code); 01696 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); 01697 if ($notkix) { 01698 // table for checksum calculation (row,col) 01699 $checktable = array( 01700 '0' => array(1,1), 01701 '1' => array(1,2), 01702 '2' => array(1,3), 01703 '3' => array(1,4), 01704 '4' => array(1,5), 01705 '5' => array(1,0), 01706 '6' => array(2,1), 01707 '7' => array(2,2), 01708 '8' => array(2,3), 01709 '9' => array(2,4), 01710 'A' => array(2,5), 01711 'B' => array(2,0), 01712 'C' => array(3,1), 01713 'D' => array(3,2), 01714 'E' => array(3,3), 01715 'F' => array(3,4), 01716 'G' => array(3,5), 01717 'H' => array(3,0), 01718 'I' => array(4,1), 01719 'J' => array(4,2), 01720 'K' => array(4,3), 01721 'L' => array(4,4), 01722 'M' => array(4,5), 01723 'N' => array(4,0), 01724 'O' => array(5,1), 01725 'P' => array(5,2), 01726 'Q' => array(5,3), 01727 'R' => array(5,4), 01728 'S' => array(5,5), 01729 'T' => array(5,0), 01730 'U' => array(0,1), 01731 'V' => array(0,2), 01732 'W' => array(0,3), 01733 'X' => array(0,4), 01734 'Y' => array(0,5), 01735 'Z' => array(0,0) 01736 ); 01737 $row = 0; 01738 $col = 0; 01739 for ($i = 0; $i < $len; ++$i) { 01740 $row += $checktable[$code{$i}][0]; 01741 $col += $checktable[$code{$i}][1]; 01742 } 01743 $row %= 6; 01744 $col %= 6; 01745 $chk = array_keys($checktable, array($row,$col)); 01746 $code .= $chk[0]; 01747 ++$len; 01748 } 01749 $k = 0; 01750 if ($notkix) { 01751 // start bar 01752 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); 01753 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 01754 $bararray['maxw'] += 2; 01755 } 01756 for ($i = 0; $i < $len; ++$i) { 01757 for ($j = 0; $j < 4; ++$j) { 01758 switch ($barmode[$code{$i}][$j]) { 01759 case 1: { 01760 $p = 0; 01761 $h = 2; 01762 break; 01763 } 01764 case 2: { 01765 $p = 0; 01766 $h = 3; 01767 break; 01768 } 01769 case 3: { 01770 $p = 1; 01771 $h = 1; 01772 break; 01773 } 01774 case 4: { 01775 $p = 1; 01776 $h = 2; 01777 break; 01778 } 01779 } 01780 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); 01781 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 01782 $bararray['maxw'] += 2; 01783 } 01784 } 01785 if ($notkix) { 01786 // stop bar 01787 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0); 01788 $bararray['maxw'] += 1; 01789 } 01790 return $bararray; 01791 } 01792 01800 protected function barcode_codabar($code) { 01801 $chr = array( 01802 '0' => '11111221', 01803 '1' => '11112211', 01804 '2' => '11121121', 01805 '3' => '22111111', 01806 '4' => '11211211', 01807 '5' => '21111211', 01808 '6' => '12111121', 01809 '7' => '12112111', 01810 '8' => '12211111', 01811 '9' => '21121111', 01812 '-' => '11122111', 01813 '$' => '11221111', 01814 ':' => '21112121', 01815 '/' => '21211121', 01816 '.' => '21212111', 01817 '+' => '11222221', 01818 'A' => '11221211', 01819 'B' => '12121121', 01820 'C' => '11121221', 01821 'D' => '11122211' 01822 ); 01823 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01824 $k = 0; 01825 $w = 0; 01826 $seq = ''; 01827 $code = 'A'.strtoupper($code).'A'; 01828 $len = strlen($code); 01829 for ($i = 0; $i < $len; ++$i) { 01830 if (!isset($chr[$code{$i}])) { 01831 return false; 01832 } 01833 $seq = $chr[$code{$i}]; 01834 for ($j = 0; $j < 8; ++$j) { 01835 if (($j % 2) == 0) { 01836 $t = true; // bar 01837 } else { 01838 $t = false; // space 01839 } 01840 $w = $seq{$j}; 01841 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 01842 $bararray['maxw'] += $w; 01843 ++$k; 01844 } 01845 } 01846 return $bararray; 01847 } 01848 01856 protected function barcode_code11($code) { 01857 $chr = array( 01858 '0' => '111121', 01859 '1' => '211121', 01860 '2' => '121121', 01861 '3' => '221111', 01862 '4' => '112121', 01863 '5' => '212111', 01864 '6' => '122111', 01865 '7' => '111221', 01866 '8' => '211211', 01867 '9' => '211111', 01868 '-' => '112111', 01869 'S' => '112211' 01870 ); 01871 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01872 $k = 0; 01873 $w = 0; 01874 $seq = ''; 01875 $len = strlen($code); 01876 // calculate check digit C 01877 $p = 1; 01878 $check = 0; 01879 for ($i = ($len - 1); $i >= 0; --$i) { 01880 $digit = $code{$i}; 01881 if ($digit == '-') { 01882 $dval = 10; 01883 } else { 01884 $dval = intval($digit); 01885 } 01886 $check += ($dval * $p); 01887 ++$p; 01888 if ($p > 10) { 01889 $p = 1; 01890 } 01891 } 01892 $check %= 11; 01893 if ($check == 10) { 01894 $check = '-'; 01895 } 01896 $code .= $check; 01897 if ($len > 10) { 01898 // calculate check digit K 01899 $p = 1; 01900 $check = 0; 01901 for ($i = $len; $i >= 0; --$i) { 01902 $digit = $code{$i}; 01903 if ($digit == '-') { 01904 $dval = 10; 01905 } else { 01906 $dval = intval($digit); 01907 } 01908 $check += ($dval * $p); 01909 ++$p; 01910 if ($p > 9) { 01911 $p = 1; 01912 } 01913 } 01914 $check %= 11; 01915 $code .= $check; 01916 ++$len; 01917 } 01918 $code = 'S'.$code.'S'; 01919 $len += 3; 01920 for ($i = 0; $i < $len; ++$i) { 01921 if (!isset($chr[$code{$i}])) { 01922 return false; 01923 } 01924 $seq = $chr[$code{$i}]; 01925 for ($j = 0; $j < 6; ++$j) { 01926 if (($j % 2) == 0) { 01927 $t = true; // bar 01928 } else { 01929 $t = false; // space 01930 } 01931 $w = $seq{$j}; 01932 $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); 01933 $bararray['maxw'] += $w; 01934 ++$k; 01935 } 01936 } 01937 return $bararray; 01938 } 01939 01947 protected function barcode_pharmacode($code) { 01948 $seq = ''; 01949 $code = intval($code); 01950 while ($code > 0) { 01951 if (($code % 2) == 0) { 01952 $seq .= '11100'; 01953 $code -= 2; 01954 } else { 01955 $seq .= '100'; 01956 $code -= 1; 01957 } 01958 $code /= 2; 01959 } 01960 $seq = substr($seq, 0, -2); 01961 $seq = strrev($seq); 01962 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); 01963 return $this->binseq_to_array($seq, $bararray); 01964 } 01965 01973 protected function barcode_pharmacode2t($code) { 01974 $seq = ''; 01975 $code = intval($code); 01976 do { 01977 switch ($code % 3) { 01978 case 0: { 01979 $seq .= '3'; 01980 $code = ($code - 3) / 3; 01981 break; 01982 } 01983 case 1: { 01984 $seq .= '1'; 01985 $code = ($code - 1) / 3; 01986 break; 01987 } 01988 case 2: { 01989 $seq .= '2'; 01990 $code = ($code - 2) / 3; 01991 break; 01992 } 01993 } 01994 } while($code != 0); 01995 $seq = strrev($seq); 01996 $k = 0; 01997 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); 01998 $len = strlen($seq); 01999 for ($i = 0; $i < $len; ++$i) { 02000 switch ($seq{$i}) { 02001 case '1': { 02002 $p = 1; 02003 $h = 1; 02004 break; 02005 } 02006 case '2': { 02007 $p = 0; 02008 $h = 1; 02009 break; 02010 } 02011 case '3': { 02012 $p = 0; 02013 $h = 2; 02014 break; 02015 } 02016 } 02017 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); 02018 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 02019 $bararray['maxw'] += 2; 02020 } 02021 unset($bararray['bcode'][($k - 1)]); 02022 --$bararray['maxw']; 02023 return $bararray; 02024 } 02025 02026 02036 protected function barcode_imb($code) { 02037 $asc_chr = array(4,0,2,6,3,5,1,9,8,7,1,2,0,6,4,8,2,9,5,3,0,1,3,7,4,6,8,9,2,0,5,1,9,4,3,8,6,7,1,2,4,3,9,5,7,8,3,0,2,1,4,0,9,1,7,0,2,4,6,3,7,1,9,5,8); 02038 $dsc_chr = array(7,1,9,5,8,0,2,4,6,3,5,8,9,7,3,0,6,1,7,4,6,8,9,2,5,1,7,5,4,3,8,7,6,0,2,5,4,9,3,0,1,6,8,2,0,4,5,9,6,7,5,2,6,3,8,5,1,9,8,7,4,0,2,6,3); 02039 $asc_pos = array(3,0,8,11,1,12,8,11,10,6,4,12,2,7,9,6,7,9,2,8,4,0,12,7,10,9,0,7,10,5,7,9,6,8,2,12,1,4,2,0,1,5,4,6,12,1,0,9,4,7,5,10,2,6,9,11,2,12,6,7,5,11,0,3,2); 02040 $dsc_pos = array(2,10,12,5,9,1,5,4,3,9,11,5,10,1,6,3,4,1,10,0,2,11,8,6,1,12,3,8,6,4,4,11,0,6,1,9,11,5,3,7,3,10,7,11,8,2,10,3,5,8,0,3,12,11,8,4,5,1,3,0,7,12,9,8,10); 02041 $code_arr = explode('-', $code); 02042 $tracking_number = $code_arr[0]; 02043 if (isset($code_arr[1])) { 02044 $routing_code = $code_arr[1]; 02045 } else { 02046 $routing_code = ''; 02047 } 02048 // Conversion of Routing Code 02049 switch (strlen($routing_code)) { 02050 case 0: { 02051 $binary_code = 0; 02052 break; 02053 } 02054 case 5: { 02055 $binary_code = bcadd($routing_code, '1'); 02056 break; 02057 } 02058 case 9: { 02059 $binary_code = bcadd($routing_code, '100001'); 02060 break; 02061 } 02062 case 11: { 02063 $binary_code = bcadd($routing_code, '1000100001'); 02064 break; 02065 } 02066 default: { 02067 return false; 02068 break; 02069 } 02070 } 02071 $binary_code = bcmul($binary_code, 10); 02072 $binary_code = bcadd($binary_code, $tracking_number{0}); 02073 $binary_code = bcmul($binary_code, 5); 02074 $binary_code = bcadd($binary_code, $tracking_number{1}); 02075 $binary_code .= substr($tracking_number, 2, 18); 02076 // convert to hexadecimal 02077 $binary_code = $this->dec_to_hex($binary_code); 02078 // pad to get 13 bytes 02079 $binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT); 02080 // convert string to array of bytes 02081 $binary_code_arr = chunk_split($binary_code, 2, "\r"); 02082 $binary_code_arr = substr($binary_code_arr, 0, -1); 02083 $binary_code_arr = explode("\r", $binary_code_arr); 02084 // calculate frame check sequence 02085 $fcs = $this->imb_crc11fcs($binary_code_arr); 02086 // exclude first 2 bits from first byte 02087 $first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2)); 02088 $binary_code_102bit = $first_byte.substr($binary_code, 2); 02089 // convert binary data to codewords 02090 $codewords = array(); 02091 $data = $this->hex_to_dec($binary_code_102bit); 02092 $codewords[0] = bcmod($data, 636) * 2; 02093 $data = bcdiv($data, 636); 02094 for ($i = 1; $i < 9; ++$i) { 02095 $codewords[$i] = bcmod($data, 1365); 02096 $data = bcdiv($data, 1365); 02097 } 02098 $codewords[9] = $data; 02099 if (($fcs >> 10) == 1) { 02100 $codewords[9] += 659; 02101 } 02102 // generate lookup tables 02103 $table2of13 = $this->imb_tables(2, 78); 02104 $table5of13 = $this->imb_tables(5, 1287); 02105 // convert codewords to characters 02106 $characters = array(); 02107 $bitmask = 512; 02108 foreach($codewords as $k => $val) { 02109 if ($val <= 1286) { 02110 $chrcode = $table5of13[$val]; 02111 } else { 02112 $chrcode = $table2of13[($val - 1287)]; 02113 } 02114 if (($fcs & $bitmask) > 0) { 02115 // bitwise invert 02116 $chrcode = ((~$chrcode) & 8191); 02117 } 02118 $characters[] = $chrcode; 02119 $bitmask /= 2; 02120 } 02121 $characters = array_reverse($characters); 02122 // build bars 02123 $k = 0; 02124 $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); 02125 for ($i = 0; $i < 65; ++$i) { 02126 $asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0); 02127 $dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0); 02128 if ($asc AND $dsc) { 02129 // full bar (F) 02130 $p = 0; 02131 $h = 3; 02132 } elseif ($asc) { 02133 // ascender (A) 02134 $p = 0; 02135 $h = 2; 02136 } elseif ($dsc) { 02137 // descender (D) 02138 $p = 1; 02139 $h = 2; 02140 } else { 02141 // tracker (T) 02142 $p = 1; 02143 $h = 1; 02144 } 02145 $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); 02146 $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); 02147 $bararray['maxw'] += 2; 02148 } 02149 unset($bararray['bcode'][($k - 1)]); 02150 --$bararray['maxw']; 02151 return $bararray; 02152 } 02153 02160 public function dec_to_hex($number) { 02161 $i = 0; 02162 $hex = array(); 02163 if($number == 0) { 02164 return '00'; 02165 } 02166 while($number > 0) { 02167 if($number == 0) { 02168 array_push($hex, '0'); 02169 } else { 02170 array_push($hex, strtoupper(dechex(bcmod($number, '16')))); 02171 $number = bcdiv($number, '16', 0); 02172 } 02173 } 02174 $hex = array_reverse($hex); 02175 return implode($hex); 02176 } 02177 02184 public function hex_to_dec($hex) { 02185 $dec = 0; 02186 $bitval = 1; 02187 $len = strlen($hex); 02188 for($pos = ($len - 1); $pos >= 0; --$pos) { 02189 $dec = bcadd($dec, bcmul(hexdec($hex{$pos}), $bitval)); 02190 $bitval = bcmul($bitval, 16); 02191 } 02192 return $dec; 02193 } 02194 02201 protected function imb_crc11fcs($code_arr) { 02202 $genpoly = 0x0F35; // generator polynomial 02203 $fcs = 0x07FF; // Frame Check Sequence 02204 // do most significant byte skipping the 2 most significant bits 02205 $data = hexdec($code_arr[0]) << 5; 02206 for ($bit = 2; $bit < 8; ++$bit) { 02207 if (($fcs ^ $data) & 0x400) { 02208 $fcs = ($fcs << 1) ^ $genpoly; 02209 } else { 02210 $fcs = ($fcs << 1); 02211 } 02212 $fcs &= 0x7FF; 02213 $data <<= 1; 02214 } 02215 // do rest of bytes 02216 for ($byte = 1; $byte < 13; ++$byte) { 02217 $data = hexdec($code_arr[$byte]) << 3; 02218 for ($bit = 0; $bit < 8; ++$bit) { 02219 if (($fcs ^ $data) & 0x400) { 02220 $fcs = ($fcs << 1) ^ $genpoly; 02221 } else { 02222 $fcs = ($fcs << 1); 02223 } 02224 $fcs &= 0x7FF; 02225 $data <<= 1; 02226 } 02227 } 02228 return $fcs; 02229 } 02230 02237 protected function imb_reverse_us($num) { 02238 $rev = 0; 02239 for ($i = 0; $i < 16; ++$i) { 02240 $rev <<= 1; 02241 $rev |= ($num & 1); 02242 $num >>= 1; 02243 } 02244 return $rev; 02245 } 02246 02254 protected function imb_tables($n, $size) { 02255 $table = array(); 02256 $lli = 0; // LUT lower index 02257 $lui = $size - 1; // LUT upper index 02258 for ($count = 0; $count < 8192; ++$count) { 02259 $bit_count = 0; 02260 for ($bit_index = 0; $bit_index < 13; ++$bit_index) { 02261 $bit_count += intval(($count & (1 << $bit_index)) != 0); 02262 } 02263 // if we don't have the right number of bits on, go on to the next value 02264 if ($bit_count == $n) { 02265 $reverse = ($this->imb_reverse_us($count) >> 3); 02266 // if the reverse is less than count, we have already visited this pair before 02267 if ($reverse >= $count) { 02268 // If count is symmetric, place it at the first free slot from the end of the list. 02269 // Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list 02270 if ($reverse == $count) { 02271 $table[$lui] = $count; 02272 --$lui; 02273 } else { 02274 $table[$lli] = $count; 02275 ++$lli; 02276 $table[$lli] = $reverse; 02277 ++$lli; 02278 } 02279 } 02280 } 02281 } 02282 return $table; 02283 } 02284 02285 } // end of class 02286 //============================================================+ 02287 // END OF FILE 02288 //============================================================+