$array2_value ) {
if ( isset($array1[$array2_key]) ) {
$array1[$array2_key] = self::array_merge_recursive($array1[$array2_key], $array2_value);
}
else {
$array1[$array2_key] = $array2_value;
}
}
return $array1;
}
/**
* Prepend a reference to an element to the beginning of an array.
* Renumbers numeric keys, so $value is always inserted to $array[0]
*
* @param $array array
* @param $value mixed
* @return int
* @access public
*/
public static function array_unshift_ref(&$array, &$value)
{
$return = array_unshift($array,'');
$array[0] =& $value;
return $return;
}
/**
* Rename key in associative array, maintaining keys order
*
* @param Array $array Associative Array
* @param mixed $old Old key name
* @param mixed $new New key name
* @access public
*/
public static function array_rename_key(&$array, $old, $new)
{
$new_array = Array ();
foreach ($array as $key => $val) {
$new_array[ $key == $old ? $new : $key] = $val;
}
$array = $new_array;
}
/**
* Same as print_r, but outputs result on screen or in debugger report (when in debug mode)
*
* @param Array $data
* @param string $label
* @param bool $on_screen
* @access public
*/
public static function print_r($data, $label = '', $on_screen = false)
{
$is_debug = false;
if ( class_exists('kApplication') && !$on_screen ) {
$application =& kApplication::Instance();
$is_debug = $application->isDebugMode();
}
if ( $is_debug && isset($application) ) {
if ( $label ) {
$application->Debugger->appendHTML('' . $label . '');
}
$application->Debugger->dumpVars($data);
}
else {
if ( $label ) {
echo '' . $label . '
';
}
echo '
', print_r($data, true), ''; } } /** * Define constant if it was not already defined before * * @param string $const_name * @param string $const_value * @access public */ public static function safeDefine($const_name, $const_value) { if ( !defined($const_name) ) { define($const_name, $const_value); } } /** * Instantiate kSystemConfig class once and store locally * * @access public */ public static function getSystemConfig() { static $system_config; if ( !isset($system_config) ) { $system_config = new kSystemConfig(); } return $system_config; } /** * Same as "include_once", but also profiles file includes in debug mode and DBG_PROFILE_INCLUDES constant is set * * @param string $file * @access public */ public static function includeOnce($file) { global $debugger; if ( defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger) && defined('DBG_PROFILE_INCLUDES') && DBG_PROFILE_INCLUDES ) { if ( in_array($file, get_included_files()) ) { return ; } global $debugger; /*$debugger->IncludeLevel++; $before_mem = memory_get_usage();*/ $debugger->ProfileStart('inc_'.crc32($file), $file); include_once($file); $debugger->ProfileFinish('inc_'.crc32($file)); $debugger->profilerAddTotal('includes', 'inc_'.crc32($file)); /*$used_mem = memory_get_usage() - $before_mem; $debugger->IncludeLevel--; $debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file); $debugger->IncludesData['mem'][] = $used_mem; $debugger->IncludesData['time'][] = $used_time; $debugger->IncludesData['level'][] = $debugger->IncludeLevel;*/ } else { include_once($file); } } /** * Checks if given string is a serialized array * * @param string $string * @return bool * @access public */ public static function IsSerialized($string) { if ( is_array($string) ) { return false; } return preg_match('/a:([\d]+):{/', $string); } /** * Generates password of given length * * @param int $length * @return string * @access public */ public static function generatePassword($length = 10) { $pass_length = $length; $p1 = Array ('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'); $p2 = Array ('a','e','i','o','u'); $p3 = Array ('1','2','3','4','5','6','7','8','9'); $p4 = Array ('(','&',')',';','%'); // if you need real strong stuff // how much elements in the array // can be done with a array count but counting once here is faster $s1 = 21;// this is the count of $p1 $s2 = 5; // this is the count of $p2 $s3 = 9; // this is the count of $p3 $s4 = 5; // this is the count of $p4 // possible readable combinations $c1 = '121'; // will be like 'bab' $c2 = '212'; // will be like 'aba' $c3 = '12'; // will be like 'ab' $c4 = '3'; // will be just a number '1 to 9' if you dont like number delete the 3 //$c5 = '4'; // uncomment to active the strong stuff $comb = '4'; // the amount of combinations you made above (and did not comment out) for ($p = 0; $p < $pass_length;) { mt_srand((double)microtime() * 1000000); $strpart = mt_rand(1, $comb); // checking if the stringpart is not the same as the previous one if ($strpart != $previous) { $pass_structure .= ${'c' . $strpart}; // shortcutting the loop a bit $p = $p + mb_strlen(${'c' . $strpart}); } $previous = $strpart; } // generating the password from the structure defined in $pass_structure for ($g = 0; $g < mb_strlen($pass_structure); $g++) { mt_srand((double)microtime() * 1000000); $sel = mb_substr($pass_structure, $g, 1); $pass .= ${'p' . $sel}[ mt_rand(0,-1+${'s'.$sel}) ]; } return $pass; } /** * submits $url with $post as POST * * @param string $url * @param mixed $data * @param Array $headers * @param string $request_type * @param Array $curl_options * @return string * @access public * @deprecated */ public static function curl_post($url, $data, $headers = NULL, $request_type = 'POST', $curl_options = NULL) { $application =& kApplication::Instance(); /** @var kCurlHelper $curl_helper */ $curl_helper = $application->recallObject('CurlHelper'); if ($request_type == 'POST') { $curl_helper->SetRequestMethod(kCurlHelper::REQUEST_METHOD_POST); } $curl_helper->SetRequestData($data); if (!is_null($headers)) { // not an associative array, so don't use kCurlHelper::SetHeaders method $curl_helper->setOptions( Array (CURLOPT_HTTPHEADER => $headers) ); } if (is_array($curl_options)) { $curl_helper->setOptions($curl_options); } $curl_helper->followLocation = false; $ret = $curl_helper->Send($url); $GLOBALS['curl_errorno'] = $curl_helper->lastErrorCode; $GLOBALS['curl_error'] = $curl_helper->lastErrorMsg; return $ret; } /** * Checks if constant is defined and has positive value * * @param string $const_name * @return bool * @access public */ public static function constOn($const_name) { return defined($const_name) && constant($const_name); } /** * Converts KG to Pounds * * @param float $kg * @param bool $pounds_only * @return float * @access public */ public static function Kg2Pounds($kg, $pounds_only = false) { $major = floor( round($kg / self::POUND_TO_KG, 3) ); $minor = abs(round(($kg - $major * self::POUND_TO_KG) / self::POUND_TO_KG * 16, 2)); if ($pounds_only) { $major += round($minor * 0.0625, 2); $minor = 0; } return array($major, $minor); } /** * Converts Pounds to KG * * @param float $pounds * @param float $ounces * @return float * @access public */ public static function Pounds2Kg($pounds, $ounces = 0.00) { return round(($pounds + ($ounces / 16)) * self::POUND_TO_KG, 5); } /** * Formats file/memory size in nice way * * @param int $bytes * @return string * @access public */ public static function formatSize($bytes) { if ($bytes >= 1099511627776) { $return = round($bytes / 1024 / 1024 / 1024 / 1024, 2); $suffix = "TB"; } elseif ($bytes >= 1073741824) { $return = round($bytes / 1024 / 1024 / 1024, 2); $suffix = "GB"; } elseif ($bytes >= 1048576) { $return = round($bytes / 1024 / 1024, 2); $suffix = "MB"; } elseif ($bytes >= 1024) { $return = round($bytes / 1024, 2); $suffix = "KB"; } else { $return = $bytes; $suffix = "Byte"; } $return .= ' '.$suffix; return $return; } /** * Enter description here... * * @param resource $filePointer the file resource to write to * @param Array $data the data to write out * @param string $delimiter the field separator * @param string $enclosure symbol to enclose field data to * @param string $recordSeparator symbols to separate records with * @access public */ public static function fputcsv($filePointer, $data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n") { fwrite($filePointer, self::getcsvline($data, $delimiter, $enclosure, $recordSeparator)); } /** * Enter description here... * * @param Array $data the data to write out * @param string $delimiter the field separator * @param string $enclosure symbol to enclose field data to * @param string $recordSeparator symbols to separate records with * @return string * @access public */ public static function getcsvline($data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n") { ob_start(); $fp = fopen('php://output', 'w'); fputcsv($fp, $data, $delimiter, $enclosure); fclose($fp); $ret = ob_get_clean(); if ( $recordSeparator != "\n" ) { return substr($ret, 0, -1) . $recordSeparator; } return $ret; } /** * Allows to replace #section# within any string with current section * * @param string $string * @return string * @access public */ public static function replaceModuleSection($string) { $application =& kApplication::Instance(); $module_section = $application->RecallVar('section'); if ($module_section) { // substitute section instead of #section# parameter in title preset name $module_section = explode(':', $module_section); $section = preg_replace('/(configuration|configure)_(.*)/i', '\\2', $module_section[count($module_section) == 2 ? 1 : 0]); $string = str_replace('#section#', mb_strtolower($section), $string); } return $string; } /** * Checks, that user IP address is within allowed range * * @param string $ip_list semi-column (by default) separated ip address list * @param string $separator ip address separator (default ";") * * @return bool * @access public */ public static function ipMatch($ip_list, $separator = ';') { if ( php_sapi_name() == 'cli' ) { return false; } $ip_match = false; $ip_addresses = $ip_list ? explode($separator, $ip_list) : Array (); $application =& kApplication::Instance(); $client_ip = $application->getClientIp(); foreach ($ip_addresses as $ip_address) { if ( self::netMatch($ip_address, $client_ip) ) { $ip_match = true; break; } } return $ip_match; } /** * Checks, that given ip belongs to given subnet * * @param string $network * @param string $ip * @return bool * @access public */ public static function netMatch($network, $ip) { $network = trim($network); $ip = trim($ip); if ( preg_replace('/[\d\.\/-]/', '', $network) != '' ) { $network = gethostbyname($network); } if ($network == $ip) { // comparing two ip addresses directly return true; } $d = strpos($network, '-'); if ($d !== false) { // ip address range specified $from = ip2long(trim(substr($network, 0, $d))); $to = ip2long(trim(substr($network, $d + 1))); $ip = ip2long($ip); return ($ip >= $from && $ip <= $to); } elseif (strpos($network, '/') !== false) { // single subnet specified $ip_arr = explode('/', $network); if (!preg_match("@\d*\.\d*\.\d*\.\d*@", $ip_arr[0], $matches)) { $ip_arr[0] .= '.0'; // Alternate form 194.1.4/24 } $network_long = ip2long($ip_arr[0]); $x = ip2long($ip_arr[1]); $mask = long2ip($x) == $ip_arr[1] ? $x : (0xffffffff << (32 - $ip_arr[1])); $ip_long = ip2long($ip); return ($ip_long & $mask) == ($network_long & $mask); } return false; } /** * Returns mime type corresponding to given file * @param string $file * @return string * @access public */ public static function mimeContentType($file) { $ret = self::vendorMimeContentType($file); if ( $ret ) { // vendor-specific mime types override any automatic detection return $ret; } if ( function_exists('finfo_open') && function_exists('finfo_file') ) { $mime_magic_resource = finfo_open(FILEINFO_MIME_TYPE); if ( $mime_magic_resource ) { $ret = finfo_file($mime_magic_resource, $file); finfo_close($mime_magic_resource); } } elseif ( function_exists('mime_content_type') ) { $ret = mime_content_type($file); } return $ret ? $ret : self::mimeContentTypeByExtension($file); } /** * Determines vendor-specific mime type from a given file * * @param string $file * @return bool * @access public * @static */ public static function vendorMimeContentType($file) { $file_extension = mb_strtolower(pathinfo(self::removeTempExtension($file), PATHINFO_EXTENSION)); $mapping = Array ( 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' ); return isset($mapping[$file_extension]) ? $mapping[$file_extension] : false; } /** * Detects mime type of the file purely based on it's extension * * @param string $file * @return string * @access public */ public static function mimeContentTypeByExtension($file) { $file_extension = mb_strtolower(pathinfo(self::removeTempExtension($file), PATHINFO_EXTENSION)); $mapping = '(xls:application/excel)(hqx:application/macbinhex40)(doc,dot,wrd:application/msword)(pdf:application/pdf) (pgp:application/pgp)(ps,eps,ai:application/postscript)(ppt:application/powerpoint)(rtf:application/rtf) (tgz,gtar:application/x-gtar)(gz:application/x-gzip)(php,php3:application/x-httpd-php)(js:application/x-javascript) (ppd,psd:application/x-photoshop)(swf,swc,rf:application/x-shockwave-flash)(tar:application/x-tar)(zip:application/zip) (mid,midi,kar:audio/midi)(mp2,mp3,mpga:audio/mpeg)(ra:audio/x-realaudio)(wav:audio/wav)(bmp:image/bitmap)(bmp:image/bitmap) (gif:image/gif)(iff:image/iff)(jb2:image/jb2)(jpg,jpe,jpeg:image/jpeg)(jpx:image/jpx)(png:image/png)(tif,tiff:image/tiff) (wbmp:image/vnd.wap.wbmp)(xbm:image/xbm)(css:text/css)(txt:text/plain)(htm,html:text/html)(xml:text/xml) (mpg,mpe,mpeg:video/mpeg)(qt,mov:video/quicktime)(avi:video/x-ms-video)(eml:message/rfc822) (sxw:application/vnd.sun.xml.writer)(sxc:application/vnd.sun.xml.calc)(sxi:application/vnd.sun.xml.impress) (sxd:application/vnd.sun.xml.draw)(sxm:application/vnd.sun.xml.math) (odt:application/vnd.oasis.opendocument.text)(oth:application/vnd.oasis.opendocument.text-web) (odm:application/vnd.oasis.opendocument.text-master)(odg:application/vnd.oasis.opendocument.graphics) (odp:application/vnd.oasis.opendocument.presentation)(ods:application/vnd.oasis.opendocument.spreadsheet) (odc:application/vnd.oasis.opendocument.chart)(odf:application/vnd.oasis.opendocument.formula) (odi:application/vnd.oasis.opendocument.image)'; if ( preg_match('/[\(,]' . $file_extension . '[,]{0,1}.*?:(.*?)\)/s', $mapping, $regs) ) { return $regs[1]; } return 'application/octet-stream'; } /** * Strips ".tmp" suffix (added by flash uploader) from a filename * * @param string $file * @return string * @access public * @static */ public static function removeTempExtension($file) { return preg_replace('/(_[\d]+)?\.tmp$/', '', $file); } /** * Return param value and removes it from params array * * @param string $name * @param Array $params * @param bool $default * @return string */ public static function popParam($name, &$params, $default = false) { if ( isset($params[$name]) ) { $value = $params[$name]; unset($params[$name]); return $value; } return $default; } /** * Generate subpath from hashed value * * @param string $name * @param int $levels * @return string */ public static function getHashPathForLevel($name, $levels = 2) { if ( $levels == 0 ) { return ''; } else { $path = ''; $hash = md5($name); for ($i = 0; $i < $levels; $i++) { $path .= substr($hash, $i, 1) . '/'; } return $path; } } /** * Calculates the crc32 polynomial of a string (always positive number) * * @param string $str * @return int */ public static function crc32($str) { return sprintf('%u', crc32($str)); } /** * Returns instance of DateTime class with date set based on timestamp * * @static * @param int $timestamp * @return DateTime * @access public */ public static function dateFromTimestamp($timestamp) { if ( version_compare(PHP_VERSION, '5.3.0', '<') ) { $date = new DateTime('@' . $timestamp); $date->setTimezone(new DateTimeZone(date_default_timezone_get())); } else { $date = new DateTime(); $date->setTimestamp($timestamp); } return $date; } /** * Returns timestamp from given DateTime class instance * * @static * @param DateTime $date_time * @return int|string * @access public */ public static function timestampFromDate(DateTime $date_time) { if ( version_compare(PHP_VERSION, '5.3.0', '<') ) { return $date_time->format('U'); } return $date_time->getTimestamp(); } /** * Generates random numeric id * * @static * @return string * @access public */ public static function generateId() { list($usec, $sec) = explode(' ', microtime()); $id_part_1 = substr($usec, 4, 4); $id_part_2 = mt_rand(1, 9); $id_part_3 = substr($sec, 6, 4); $digit_one = substr($id_part_1, 0, 1); if ( $digit_one == 0 ) { $digit_one = mt_rand(1, 9); $id_part_1 = preg_replace('/^0/', '', $id_part_1); $id_part_1 = $digit_one . $id_part_1; } return $id_part_1 . $id_part_2 . $id_part_3; } /** * Changes script resource limits. Omitted argument results in limit removal. * * @static * @param string|int $memory_limit * @param int $time_limit * @return void * @access public */ public static function setResourceLimit($memory_limit = null, $time_limit = null) { set_time_limit(isset($time_limit) ? $time_limit : 0); ini_set('memory_limit', isset($memory_limit) ? $memory_limit : -1); } /** * Escapes a string. * * @param string $text Text to escape. * @param string $strategy Escape strategy. * * @return string * @throws InvalidArgumentException When unknown escape strategy is given. */ public static function escape($text, $strategy = null) { if ( !isset($strategy) ) { $strategy = self::$escapeStrategy; } if ( strpos($strategy, '+') !== false ) { $previous_strategy = ''; $strategies = explode('+', $strategy); foreach ($strategies as $current_strategy) { // apply default strategy if ( $current_strategy == '' ) { $current_strategy = self::$escapeStrategy; } // don't double-escape if ( $current_strategy != $previous_strategy ) { $text = self::escape($text, $current_strategy); $previous_strategy = $current_strategy; } } return $text; } if ( $strategy == self::ESCAPE_HTML ) { return htmlspecialchars($text, ENT_QUOTES, CHARSET); } if ( $strategy == self::ESCAPE_JS ) { // TODO: consider using "addcslashes", because "addslashes" isn't really for JavaScript escaping (according to docs) $text = addslashes($text); $text = str_replace(array("\r", "\n"), array('\r', '\n'), $text); $text = str_replace('', "'+'script>", $text); return $text; } if ( $strategy == self::ESCAPE_URL ) { return rawurlencode($text); } if ( $strategy == self::ESCAPE_RAW ) { return $text; } throw new InvalidArgumentException(sprintf('Unknown escape strategy "%s"', $strategy)); } /** * Unescapes a string. * * @param string $text Text to unescape. * @param string $strategy Escape strategy. * * @return string * @throws InvalidArgumentException When unknown escape strategy is given. */ public static function unescape($text, $strategy = null) { if ( !isset($strategy) ) { $strategy = self::$escapeStrategy; } if ( strpos($strategy, '+') !== false ) { $previous_strategy = ''; $strategies = explode('+', $strategy); foreach ($strategies as $current_strategy) { // apply default strategy if ( $current_strategy == '' ) { $current_strategy = self::$escapeStrategy; } // don't double-unescape if ( $current_strategy != $previous_strategy ) { $text = self::unescape($text, $current_strategy); $previous_strategy = $current_strategy; } } return $text; } if ( $strategy == self::ESCAPE_HTML ) { return htmlspecialchars_decode($text, ENT_QUOTES); } if ( $strategy == self::ESCAPE_JS ) { // TODO: consider using "stripcslashes", because "stripslashes" isn't really for JavaScript unescaping (according to docs) $text = str_replace("'+'script>", '', $text); $text = str_replace(array('\r', '\n'), array("\r", "\n"), $text); $text = stripslashes($text); return $text; } if ( $strategy == self::ESCAPE_URL ) { return rawurldecode($text); } if ( $strategy == self::ESCAPE_RAW ) { return $text; } throw new InvalidArgumentException(sprintf('Unknown escape strategy "%s"', $strategy)); } /** * Mark a method as deprecated and inform when it has been used. * * The current behavior is to trigger a user deprecation notice in Debug Mode. * This method is to be used in every method that is deprecated. * * @param string $method The method that was called. * @param string $version The version that deprecated the method. * @param string|null $replacement The method that should have been called. * * @return void */ public static function deprecatedMethod($method, $version, $replacement = null) { $application =& kApplication::Instance(); if ( !$application->isDebugMode() ) { return; } $msg = '%1$s is deprecated since version %2$s'; if ( !is_null($replacement) ) { @trigger_error(sprintf($msg . '! Use %3$s instead.', $method, $version, $replacement), E_USER_DEPRECATED); } else { @trigger_error(sprintf($msg . ' with no alternative available.', $method, $version), E_USER_DEPRECATED); } } /** * Mark a method argument as deprecated and inform when it has been used. * * This method is to be used whenever a deprecated method argument is used. * Before this method is called, the argument must be checked for whether it was * used by comparing it to its default value or evaluating whether it is empty. * For example: * * if ( !$deprecated ) { * kUtil::deprecatedArgument(__METHOD__, '5.2.2'); * } * * The current behavior is to trigger a user deprecation notice in Debug Mode. * * @param string $method The method that was called. * @param string $version The version that deprecated the argument used. * @param string|null $message A message regarding the change. * * @return void */ public static function deprecatedArgument($method, $version, $message = null) { $application =& kApplication::Instance(); if ( !$application->isDebugMode() ) { return; } $msg = '%1$s was called with an argument that is deprecated since version %2$s'; if ( !is_null($message) ) { @trigger_error(sprintf($msg . '! %3$s', $method, $version, $message), E_USER_DEPRECATED); } else { @trigger_error(sprintf($msg . ' with no alternative available.', $method, $version), E_USER_DEPRECATED); } } /** * Parse ini size * * @param string $size Size. * * @return integer */ public static function parseIniSize($size) { $result = (int)$size; $size = strtolower($size); if ( strpos($size, 'k') ) { return $result * 1024; } if ( strpos($size, 'm') ) { return $result * 1024 * 1024; } if ( strpos($size, 'g') ) { return $result * 1024 * 1024 * 1024; } return $result; } } /** * Returns array value if key exists * Accepts infinite number of parameters * * @param Array $array searchable array * @param int $key array key * @return string */ function getArrayValue(&$array, $key) { $ret = isset($array[$key]) ? $array[$key] : false; if ( $ret && func_num_args() > 2 ) { for ($i = 2; $i < func_num_args(); $i++) { $cur_key = func_get_arg($i); $ret = getArrayValue($ret, $cur_key); if ( $ret === false ) { break; } } } return $ret; } if ( !function_exists('parse_ini_string') ) { /** * Equivalent for "parse_ini_string" function available since PHP 5.3.0 * * @param string $ini * @param bool $process_sections * @param int $scanner_mode * @return Array */ function parse_ini_string($ini, $process_sections = false, $scanner_mode = NULL) { # Generate a temporary file. $tempname = tempnam('/tmp', 'ini'); $fp = fopen($tempname, 'w'); fwrite($fp, $ini); $ini = parse_ini_file($tempname, !empty($process_sections)); fclose($fp); @unlink($tempname); return $ini; } } if ( !function_exists('memory_get_usage') ) { // PHP 4.x and compiled without --enable-memory-limit option function memory_get_usage() { return -1; } } if ( !function_exists('imagecreatefrombmp') ) { // just in case if GD will add this function in future function imagecreatefrombmp($filename) { //Ouverture du fichier en mode binaire if (! $f1 = fopen($filename,"rb")) return FALSE; //1 : Chargement des ent�tes FICHIER $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14)); if ($FILE['file_type'] != 19778) return FALSE; //2 : Chargement des ent�tes BMP $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'. '/Vcompression/Vsize_bitmap/Vhoriz_resolution'. '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40)); $BMP['colors'] = pow(2,$BMP['bits_per_pixel']); if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8; $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); $BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4); $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4); $BMP['decal'] = 4-(4*$BMP['decal']); if ($BMP['decal'] == 4) $BMP['decal'] = 0; //3 : Chargement des couleurs de la palette $PALETTE = array(); if ($BMP['colors'] < 16777216) { $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); } //4 : Cr�ation de l'image $IMG = fread($f1,$BMP['size_bitmap']); $VIDE = chr(0); $res = imagecreatetruecolor($BMP['width'],$BMP['height']); $P = 0; $Y = $BMP['height']-1; while ($Y >= 0) { $X=0; while ($X < $BMP['width']) { if ($BMP['bits_per_pixel'] == 24) $COLOR = unpack("V",substr($IMG,$P,3).$VIDE); elseif ($BMP['bits_per_pixel'] == 16) { $COLOR = unpack("n",substr($IMG,$P,2)); $COLOR[1] = $PALETTE[$COLOR[1]+1]; } elseif ($BMP['bits_per_pixel'] == 8) { $COLOR = unpack("n",$VIDE.substr($IMG,$P,1)); $COLOR[1] = $PALETTE[$COLOR[1]+1]; } elseif ($BMP['bits_per_pixel'] == 4) { $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F); $COLOR[1] = $PALETTE[$COLOR[1]+1]; } elseif ($BMP['bits_per_pixel'] == 1) { $COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7; elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6; elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5; elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4; elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3; elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2; elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1; elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1); $COLOR[1] = $PALETTE[$COLOR[1]+1]; } else return FALSE; imagesetpixel($res,$X,$Y,$COLOR[1]); $X++; $P += $BMP['bytes_per_pixel']; } $Y--; $P+=$BMP['decal']; } //Fermeture du fichier fclose($f1); return $res; } }