<?php /* AUTHOR: Walter Cattebeke DATE: 08-July-2004 EMAIL: cachiweb@telesurf.com.py LICENSE: This code is free. You can use it and/or modify it. I only want to be mentioned and notified if you intend to do either. Please read the notes.txt ! Keep this module free of echo's. Just delete or comment any line I've forgotten to do so. */ define("BC_TYPE_CODE39", 1); define("BC_TYPE_INTER25", 2); define("BC_TYPE_STD25", 3); define("BC_TYPE_CODE93", 4); define("BC_TYPE_ROYMAIL4", 5); define("BC_TYPE_POSTNET", 6); define("BC_IMG_TYPE_PNG", 1); define("BC_IMG_TYPE_JPG", 2); define("BC_IMG_TYPE_GIF", 3); define("BC_IMG_TYPE_WBMP", 4); define("BC_ROTATE_0", 0); define("BC_ROTATE_90", 1); define("BC_ROTATE_180", 2); define("BC_ROTATE_270", 3); function getBarcodeText($i, $txt){ switch ($i) { case BC_TYPE_CODE39: /* Code 39 needs starting and ending special control chars (ascii asterisk). */ return strtoupper("*" . $txt . "*"); // add starting and ending control chars to original text break; case BC_TYPE_INTER25: /* Interleaved 2 of 5 needs an even number of chars and starting - ending special control chars. Because of the "interleave" this control chars are made of the "asterisk asterisk" (**) and "plus minus" (+-) combinations. */ if (strlen($txt) % 2 == 0){ return "**" . $txt . "+-"; } // OK, even length else{ return "**" . "0" . $txt . "+-"; } // make it even by adding a starting 0 break; case BC_TYPE_STD25: /* Standard 2 of 5 needs narrow spaces between bars. This is done by "interleaving" chars with special control char "dollar" ($). It also uses a special start (%!) stop (&!) combination. */ $txt1 = $txt . $txt; for ($j=0; $j<strlen($txt); $j++){ $txt1[$j*2] = $txt[$j]; $txt1[$j*2+1] = "$"; } return "%!" . $txt1 . "&!"; break; case BC_TYPE_CODE93: /* Code 93 needs starting and ending special control chars (ascii asterisk). Special @ sign is used to put safe final bar */ return strtoupper("*" . $txt . "*" . "@"); // add starting and ending control chars to original text break; case BC_TYPE_ROYMAIL4: /* Royal Mail needs starting and ending special control chars (ascii '(' and ')'). */ return strtoupper("*" . $txt . "+"); // add starting and ending control chars to original text break; case BC_TYPE_POSTNET: /* Postnet needs starting and ending special control chars (ascii asterisk). */ return strtoupper("*" . $txt . "*"); // add starting and ending control chars to original text break; default: return $txt; break; } } function checkCheckDigit($type, $ck){ switch ($type) { case BC_TYPE_CODE93: case BC_TYPE_ROYMAIL4: case BC_TYPE_POSTNET: return TRUE; // mandatory check digit break; case BC_TYPE_STD25: case BC_TYPE_INTER25: case BC_TYPE_CODE39: return $ck; // user selection break; default: return FALSE; // no check digit break; } } function checkCharGap($i, $ig){ switch ($i) { case BC_TYPE_CODE39: case BC_TYPE_ROYMAIL4: case BC_TYPE_POSTNET: return $ig; // use gap break; case BC_TYPE_STD25: case BC_TYPE_INTER25: case BC_TYPE_CODE93: return 0; // no gap break; default: return 1; // return 1 pixel width gap break; } } function checkWideToNarrow($i, $wtn){ switch ($i) { case BC_TYPE_CODE39: case BC_TYPE_STD25: case BC_TYPE_INTER25: return $wtn; // user selection break; case BC_TYPE_CODE93: case BC_TYPE_ROYMAIL4: case BC_TYPE_POSTNET: return 1; // no wide2narrow in this type break; default: return 2; // return wide to narrow factor of 2 break; } } function getCharCount($i, $txt){ switch ($i) { case BC_TYPE_CODE39: case BC_TYPE_CODE93: case BC_TYPE_ROYMAIL4: case BC_TYPE_POSTNET: return strlen($txt); // same as message length break; case BC_TYPE_STD25: case BC_TYPE_INTER25: return strlen($txt) / 2; // half the message length (interleaved) break; default: return strlen($txt); // same as message length break; } } function getBarcodeLength($i, $txt, $xd, $wtn, $qz, $ig){ switch ($i) { case BC_TYPE_CODE39: return strlen($txt) * ( 6 * $xd + 3 * $xd * $wtn) // message width + (strlen($txt) - 1) * $ig // interchar gap width + 2 * $qz; // quiet zone width break; case BC_TYPE_INTER25: return (strlen($txt) - 4) * ( 3 * $xd + 2 * $xd * $wtn) // message width + 2 * $qz // quiet zone width + ( 6 * $xd + 1 * $xd * $wtn); // control chars width break; case BC_TYPE_STD25: return (strlen($txt) - 4) / 2 * ( 3 * $xd + 2 * $xd * $wtn) // message width + (strlen($txt) - 4) / 2 * ( 5 * $ig ) // interchar gap width + 2 * $qz // quiet zone width + ( 8 * $xd + 4 * $xd * $wtn); // control chars width break; case BC_TYPE_CODE93: return (strlen($txt) - 1) * 9 * $xd // message width + 2 * $qz // quiet zone width + 1 * $xd; // final bar width break; case BC_TYPE_ROYMAIL4: return (strlen($txt) - 2) * 7 * $xd + 2 * $xd // message width + (strlen($txt) - 1) * $ig // interchar gap width + 2 * $qz; // quiet zone width break; case BC_TYPE_POSTNET: return (strlen($txt) - 2) * 9 * $xd + 2 * $xd // message width + (strlen($txt) - 1) * $ig // interchar gap width + 2 * $qz; // quiet zone width break; default: return 0; break; } } function barcodeImgFunction($i){ switch ($i) { case BC_IMG_TYPE_PNG: return "imagepng"; break; case BC_IMG_TYPE_JPG: return "imagejpeg"; break; case BC_IMG_TYPE_GIF: return "imagegif"; break; case BC_IMG_TYPE_WBMP: return "imagewbmp"; break; default: return "imagepng"; break; } } function barcodeFileExt($i){ switch ($i) { case BC_IMG_TYPE_PNG: return "png"; break; case BC_IMG_TYPE_JPG: return "jpg"; break; case BC_IMG_TYPE_GIF: return "gif"; break; case BC_IMG_TYPE_WBMP: return "wbmp"; break; default: return "png"; break; } } function barcodeHeaderContent($i){ switch ($i) { case BC_IMG_TYPE_PNG: return "image/png"; break; case BC_IMG_TYPE_JPG: return "image/jpeg"; break; case BC_IMG_TYPE_GIF: return "image/gif"; break; case BC_IMG_TYPE_WBMP: return "image/vnd.wap.wbmp"; break; default: return "image/png"; break; } } function code39spec($i) { /* Code 39 specification for symbols (index represented by ascii codes) n -> narrow bar w -> wide bar */ $arrSpec = array ( 48 => "nnnwwnwnn", // 0 49 => "wnnwnnnnw", // 1 50 => "nnwwnnnnw", // 2 51 => "wnwwnnnnn", // 3 52 => "nnnwwnnnw", // 4 53 => "wnnwwnnnn", // 5 54 => "nnwwwnnnn", // 6 55 => "nnnwnnwnw", // 7 56 => "wnnwnnwnn", // 8 57 => "nnwwnnwnn", // 9 65 => "wnnnnwnnw", // A 66 => "nnwnnwnnw", // B 67 => "wnwnnwnnn", // C 68 => "nnnnwwnnw", // D 69 => "wnnnwwnnn", // E 70 => "nnwnwwnnn", // F 71 => "nnnnnwwnw", // G 72 => "wnnnnwwnn", // H 73 => "nnwnnwwnn", // I 74 => "nnnnwwwnn", // J 75 => "wnnnnnnww", // K 76 => "nnwnnnnww", // L 77 => "wnwnnnnwn", // M 78 => "nnnnwnnww", // N 79 => "wnnnwnnwn", // O 80 => "nnwnwnnwn", // P 81 => "nnnnnnwww", // Q 82 => "wnnnnnwwn", // R 83 => "nnwnnnwwn", // S 84 => "nnnnwnwwn", // T 85 => "wwnnnnnnw", // U 86 => "nwwnnnnnw", // V 87 => "wwwnnnnnn", // W 88 => "nwnnwnnnw", // X 89 => "wwnnwnnnn", // Y 90 => "nwwnwnnnn", // Z 45 => "nwnnnnwnw", // - 46 => "wwnnnnwnn", // . 32 => "nwwnnnwnn", // SPACE 36 => "nwnwnwnnn", // $ 47 => "nwnwnnnwn", // / 43 => "nwnnnwnwn", // + 37 => "nnnwnwnwn", // % 42 => "nwnnwnwnn" // * ); return $arrSpec[$i]; } function code93spec($i) { /* Code 93 specification for symbols (index represented by ascii codes) 1 -> bar (black bar) 0 -> space (white bar) */ $arrSpec = array ( 48 => "100010100", // 0 49 => "101001000", // 1 50 => "101000100", // 2 51 => "101000010", // 3 52 => "100101000", // 4 53 => "100100100", // 5 54 => "100100010", // 6 55 => "101010000", // 7 56 => "100010010", // 8 57 => "100001010", // 9 65 => "110101000", // A 66 => "110100100", // B 67 => "110100010", // C 68 => "110010100", // D 69 => "110010010", // E 70 => "110001010", // F 71 => "101101000", // G 72 => "101100100", // H 73 => "101100010", // I 74 => "100110100", // J 75 => "100011010", // K 76 => "101011000", // L 77 => "101001100", // M 78 => "101000110", // N 79 => "100101100", // O 80 => "100010110", // P 81 => "110110100", // Q 82 => "110110010", // R 83 => "110101100", // S 84 => "110100110", // T 85 => "110010110", // U 86 => "110011010", // V 87 => "101101100", // W 88 => "101100110", // X 89 => "100110110", // Y 90 => "100111010", // Z 45 => "100101110", // - 46 => "111010100", // . 32 => "111010010", // SPACE 36 => "111001010", // $ 47 => "101101110", // / 43 => "101110110", // + 37 => "110101110", // % 60 => "100100110", // < -> ($) 61 => "111011010", // = -> (%) 62 => "111010110", // > -> (/) 63 => "100110010", // ? -> (+) 42 => "101011110", // * 64 => "1 " // @ special safe final bar !!! ); return trim($arrSpec[$i]); } function code393char2value($i) { /* Code 93 specification for symbols (index represented by ascii codes) Used for check digit calculation. */ $arrSpec = array ( 48 => "0", // 0 49 => "1", // 1 50 => "2", // 2 51 => "3", // 3 52 => "4", // 4 53 => "5", // 5 54 => "6", // 6 55 => "7", // 7 56 => "8", // 8 57 => "9", // 9 65 => "10", // A 66 => "11", // B 67 => "12", // C 68 => "13", // D 69 => "14", // E 70 => "15", // F 71 => "16", // G 72 => "17", // H 73 => "18", // I 74 => "19", // J 75 => "20", // K 76 => "21", // L 77 => "22", // M 78 => "23", // N 79 => "24", // O 80 => "25", // P 81 => "26", // Q 82 => "27", // R 83 => "28", // S 84 => "29", // T 85 => "30", // U 86 => "31", // V 87 => "32", // W 88 => "33", // X 89 => "34", // Y 90 => "35", // Z 45 => "36", // - 46 => "37", // . 32 => "38", // SPACE 36 => "39", // $ 47 => "40", // / 43 => "41", // + 37 => "42", // % 60 => "43", // < -> ($) 61 => "44", // = -> (%) 62 => "45", // > -> (/) 63 => "46", // ? -> (+) 64 => "1 " // @ special safe final bar !!! ); return trim($arrSpec[$i]); } function code393value2char($i) { /* Code 93 specification for symbols (index represented by ascii codes) Used for check digit calculation. */ $arrSpec = array ( 0 => "0", // 0 1 => "1", // 1 2 => "2", // 2 3 => "3", // 3 4 => "4", // 4 5 => "5", // 5 6 => "6", // 6 7 => "7", // 7 8 => "8", // 8 9 => "9", // 9 10 => "A", // A 11 => "B", // B 12 => "C", // C 13 => "D", // D 14 => "E", // E 15 => "F", // F 16 => "G", // G 17 => "H", // H 18 => "I", // I 19 => "J", // J 20 => "K", // K 21 => "L", // L 22 => "M", // M 23 => "N", // N 24 => "O", // O 25 => "P", // P 26 => "Q", // Q 27 => "R", // R 28 => "S", // S 29 => "T", // T 30 => "U", // U 31 => "V", // V 32 => "W", // W 33 => "X", // X 34 => "Y", // Y 35 => "Z", // Z 36 => "-", // - 37 => ".", // . 38 => " ", // SPACE 39 => "$", // $ 40 => "/", // / 41 => "+", // + 42 => "%", // % 43 => "<", // < -> ($) 44 => "=", // = -> (%) 45 => ">", // > -> (/) 46 => "?", // ? -> (+) ); return $arrSpec[$i]; } function std25spec($i) { /* Standard 2 of 5 specification for symbols (index represented by ascii codes). Also used for Interleaved 2 of 5. Some special signs ($*+-%&!) are introduced to manage special control chars. n -> narrow bar w -> wide bar */ $arrSpec = array ( 48 => "nnwwn", // 0 49 => "wnnnw", // 1 50 => "nwnnw", // 2 51 => "wwnnn", // 3 52 => "nnwnw", // 4 53 => "wnwnn", // 5 54 => "nwwnn", // 6 55 => "nnnww", // 7 56 => "wnnwn", // 8 57 => "nwnwn", // 9 36 => "nnnnn", // dollar sign ($) used for standard 2 of 5 37 => "wwn ", // percent sign (%) used for control char 38 => "wnw ", // ampersand sign (&) used for control char 33 => "nnn ", // sign (!) used for control char 42 => "nn ", // asterisk sign (*) used for control char 43 => "wn ", // plus sign (+) used for control char 45 => "n " // minus sign (-) used for control char ); return $arrSpec[$i]; } function postnetspec($i) { /* Royal Mail 4-State specification for symbols (index represented by ascii codes). Some special signs (*) are introduced to manage special control chars. f -> full bar u -> upper half bar l -> lower half bar */ $arrSpec = array ( 48 => "fffflflfl", // 0 49 => "lflflffff", // 1 50 => "lflffflff", // 2 51 => "lflfffffl", // 3 52 => "lffflflff", // 4 53 => "lffflfffl", // 5 54 => "lffffflfl", // 6 55 => "fflflflff", // 7 56 => "fflflfffl", // 8 57 => "fflffflfl", // 9 42 => "f ", // asterisk sign '*' used for start & stop bar ); return $arrSpec[$i]; } function roymail4spec($i) { /* Royal Mail 4-State specification for symbols (index represented by ascii codes). Some special signs, '*' & '+', are introduced to manage special control chars. f -> full bar t -> track only bar a -> track & ascender bar d -> track & descender bar */ $arrSpec = array ( 48 => "tftffff", // 0 49 => "tfdfaff", // 1 50 => "tfdfffa", // 2 51 => "dftfaff", // 3 52 => "dftfffa", // 4 53 => "dfdfafa", // 5 54 => "tfafdff", // 6 55 => "tffftff", // 7 56 => "tfffdfa", // 8 57 => "dfaftff", // 9 65 => "dfafdfa", // A 66 => "dffftfa", // B 67 => "tfafffd", // C 68 => "tfffafd", // D 69 => "tffffft", // E 70 => "dfafafd", // F 71 => "dfaffft", // G 72 => "dfffaft", // H 73 => "aftfdff", // I 74 => "afdftff", // J 75 => "afdfdfa", // K 76 => "fftftff", // L 77 => "fftfdfa", // M 78 => "ffdftfa", // N 79 => "aftfffd", // O 80 => "afdfafd", // P 81 => "afdffft", // Q 82 => "fftfafd", // R 83 => "fftffft", // S 84 => "ffdfaft", // T 85 => "afafdfd", // U 86 => "affftfd", // V 87 => "afffdft", // W 88 => "ffaftfd", // X 89 => "ffafdft", // Y 90 => "fffftft", // Z 42 => " a", // parenthesis sign '*' used for start char 43 => "f " // parenthesis sign '+' used for stop char ); return $arrSpec[$i]; } function roymail4value2char($row, $col) { /* Royal Mail 4-State check digit calculation table. */ $arrSpec = array ( 1 => "501234", // 0 2 => "B6789A", // 1 3 => "HCDEFG", // 2 4 => "NIJKLM", // 3 5 => "TOPQRS", // 4 0 => "ZUVWXY" // 5 ); return $arrSpec[$row][$col]; } function interleaveChars($c1, $c2) { $tmp1 = trim(std25spec($c1)); $tmp2 = trim(std25spec($c2)); $tmp = $tmp1 . $tmp2; if (($c1 >= 48) && ($c1 <= 57) && ($c2 >= 48) && ($c2 <= 57)) { for ($i=0; $i<strlen($tmp1); $i++) { $tmp[$i*2] = $tmp1[$i]; $tmp[($i*2)+1] = $tmp2[$i]; } } return trim($tmp); } function safeStr($i, $auxStr){ // check whether a string has only valid chars or not switch ($i) { case BC_TYPE_CODE39: case BC_TYPE_CODE93: $charList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; // asterisk (*) not included break; case BC_TYPE_INTER25: case BC_TYPE_STD25: case BC_TYPE_POSTNET: $charList = "0123456789"; break; case BC_TYPE_ROYMAIL4: $charList = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; break; default: return 0; break; } for($j=0; $j<strlen($auxStr); $j++){ if (strpos($charList, $auxStr[$j]) === FALSE){ return FALSE; } } return TRUE; } function getSpec($type, $txt, $i) { switch ($type) { case BC_TYPE_CODE39: return code39spec(ord($txt[$i])); break; case BC_TYPE_STD25: case BC_TYPE_INTER25: return interleaveChars(ord($txt[$i*2]), ord($txt[$i*2+1])); break; case BC_TYPE_CODE93: return code93spec(ord($txt[$i])); break; case BC_TYPE_ROYMAIL4: return roymail4spec(ord($txt[$i])); break; case BC_TYPE_POSTNET: return postnetspec(ord($txt[$i])); break; default: // treat as code39 return code39spec(ord($txt[$i])); break; } } function getCheckDigit($type, $txt) { $stLen = strlen($txt); switch ($type) { case BC_TYPE_CODE39: // modulo 43 $ck = 0; for ($i=0; $i<$stLen; $i++){ $ck = $ck + code393char2value(ord($txt[$i])); } return $txt . code393value2char($ck % 43); break; case BC_TYPE_CODE93: // C y K check digits. Modulo 47 $ck = 0; for ($i=0; $i<$stLen; $i++){ $ck = $ck + code393char2value(ord($txt[$stLen - $i -1])) * ($i % 20 + 1); } $txt1 = $txt . code393value2char($ck % 47); $stLen++; $ck = 0; for ($i=0; $i<$stLen; $i++){ $ck = $ck + code393char2value(ord($txt1[$stLen - $i -1])) * ($i % 15 + 1); } return $txt1 . code393value2char($ck % 47); break; case BC_TYPE_STD25: case BC_TYPE_INTER25: // modulo 10 $ck = 0; for ($i=0; $i<$stLen; $i++){ $w = ($i%2==0)?3:1; $ck = $ck + $txt[$stLen -1 -$i] * $w; } $ex = (10 - ($ck % 10)) % 10; return $txt . $ex; break; case BC_TYPE_ROYMAIL4: $lh = 0; $uh = 0; for ($i=0; $i<$stLen; $i++){ $chrSpec = strrev(getSpec($type, $txt, $i)); $tlh = 0; $tuh = 0; for ($j=0; $j<4; $j++) { switch (ord($chrSpec[$j*2])) { case ord("f"): $um=1; $lm=1; break; case ord("t"): $um=0; $lm=0; break; case ord("a"): $um=1; $lm=0; break; case ord("d"): $um=0; $lm=1; break; default: $um=0; $lm=0; break; } if ($j > 0) $bw = pow(2, $j-1); else $bw = 0; $tlh = $tlh + $bw * $lm; $tuh = $tuh + $bw * $um; } if ($tlh == 6) $tlh = 0; if ($tuh == 6) $tuh = 0; $uh = $uh + $tuh; $lh = $lh + $tlh; } return $txt . roymail4value2char($uh % 6, $lh % 6); break; case BC_TYPE_POSTNET: $ck = 0; for ($i=0; $i<$stLen; $i++){ $ck = $ck + $txt[$i]; } $ex = (10 - ($ck % 10)) % 10; return $txt . $ex; break; default: return $txt; break; } } ?>