Changeset 3544


Ignore:
Timestamp:
07/07/09 22:27:37 (11 years ago)
Author:
vdigital
Message:

Change: getid3 upgraded to -> 1.7.9

Location:
extensions/charlies_content/getid3/getid3
Files:
20 added
10 deleted
47 edited

Legend:

Unmodified
Added
Removed
  • extensions/charlies_content/getid3/getid3/extension.cache.dbm.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | extension.cache.mysql.php                                            | 
    18 // | MySQL Cache Extension.                                               | 
    19 // | dependencies: getid3.                                                | 
    20 // +----------------------------------------------------------------------+ 
    21 // 
    22 // $Id$ 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7//                                                             // 
     8// extension.cache.dbm.php - part of getID3()                  // 
     9// Please see readme.txt for more information                  // 
     10//                                                            /// 
     11///////////////////////////////////////////////////////////////// 
     12//                                                             // 
     13// This extension written by Allan Hansen <ahØartemis*dk>      // 
     14//                                                            /// 
     15///////////////////////////////////////////////////////////////// 
    2316 
    2417 
     
    2720* way as the getID3 class, but return cached information very fast 
    2821* 
    29 * Example:  (see also demo.cache.dbm.php in /demo/) 
     22* Example: 
    3023* 
    3124*    Normal getID3 usage (example): 
    3225* 
    3326*       require_once 'getid3/getid3.php'; 
    34 *       $getid3 = new getid3; 
    35 *       $getid3->encoding = 'UTF-8'; 
    36 *       try {  
    37 *           $info1 = $getid3->Analyse('file1.flac'); 
    38 *           $info2 = $getid3->Analyse('file2.wv'); 
    39 *           .... 
     27*       $getID3 = new getID3; 
     28*       $getID3->encoding = 'UTF-8'; 
     29*       $info1 = $getID3->analyze('file1.flac'); 
     30*       $info2 = $getID3->analyze('file2.wv'); 
    4031* 
    4132*    getID3_cached usage: 
    4233* 
    4334*       require_once 'getid3/getid3.php'; 
    44 *       require_once 'getid3/getid3/extension.cache.mysql.php'; 
    45 *       $getid3 = new getid3_cached_mysql('localhost', 'database', 'username', 'password'); 
    46 *       $getid3->encoding = 'UTF-8'; 
    47 *       try { 
    48 *           $info1 = $getid3->analyse('file1.flac'); 
    49 *           $info2 = $getid3->analyse('file2.wv'); 
    50 *           ... 
     35*       require_once 'getid3/getid3/extension.cache.dbm.php'; 
     36*       $getID3 = new getID3_cached('db3', '/tmp/getid3_cache.dbm', 
     37*                                          '/tmp/getid3_cache.lock'); 
     38*       $getID3->encoding = 'UTF-8'; 
     39*       $info1 = $getID3->analyze('file1.flac'); 
     40*       $info2 = $getID3->analyze('file2.wv'); 
    5141* 
    5242* 
     
    8070 
    8171 
    82 class getid3_cached_dbm extends getid3 
     72class getID3_cached_dbm extends getID3 
    8373{ 
    8474 
    85     public function __construct($cache_type, $dbm_filename, $lock_filename) { 
    86  
    87         // Check for dba extension 
    88         if (!extension_loaded('dba')) { 
    89             throw new getid3_exception('PHP is not compiled with dba support, required to use DBM style cache.'); 
    90         } 
    91  
    92         if (!in_array($cache_type, dba_handlers())) { 
    93             throw new getid3_exception('PHP is not compiled --with '.$cache_type.' support, required to use DBM style cache.'); 
    94         } 
    95  
    96         // Create lock file if needed 
    97         if (!file_exists($lock_filename)) { 
    98             if (!touch($lock_filename)) { 
    99                 die('failed to create lock file: ' . $lock_filename); 
    100             } 
    101         } 
    102  
    103         // Open lock file for writing 
    104         if (!is_writeable($lock_filename)) { 
    105             die('lock file: ' . $lock_filename . ' is not writable'); 
    106         } 
    107         $this->lock = fopen($lock_filename, 'w'); 
    108  
    109         // Acquire exclusive write lock to lock file 
    110         flock($this->lock, LOCK_EX); 
    111  
    112         // Create dbm-file if needed 
    113         if (!file_exists($dbm_filename)) { 
    114             if (!touch($dbm_filename)) { 
    115                 die('failed to create dbm file: ' . $dbm_filename); 
    116             } 
    117         } 
    118  
    119         // Try to open dbm file for writing 
    120         $this->dba = @dba_open($dbm_filename, 'w', $cache_type); 
    121         if (!$this->dba) { 
    122  
    123             // Failed - create new dbm file 
    124             $this->dba = dba_open($dbm_filename, 'n', $cache_type); 
    125  
    126             if (!$this->dba) { 
    127                 die('failed to create dbm file: ' . $dbm_filename); 
    128             } 
    129  
    130             // Insert getID3 version number 
    131             dba_insert(getid3::VERSION, getid3::VERSION, $this->dba); 
    132         } 
    133  
    134         // Init misc values 
    135         $this->cache_type   = $cache_type; 
    136         $this->dbm_filename = $dbm_filename; 
    137  
    138         // Register destructor 
    139         register_shutdown_function(array($this, '__destruct')); 
    140  
    141         // Check version number and clear cache if changed 
    142         if (dba_fetch(getid3::VERSION, $this->dba) != getid3::VERSION) { 
    143             $this->clear_cache(); 
    144         } 
    145  
    146         parent::__construct(); 
    147     } 
    148  
    149  
    150  
    151     public function __destruct() { 
    152  
    153         // Close dbm file 
    154         @dba_close($this->dba); 
    155  
    156         // Release exclusive lock 
    157         @flock($this->lock, LOCK_UN); 
    158  
    159         // Close lock file 
    160         @fclose($this->lock); 
    161     } 
    162  
    163  
    164  
    165     public function clear_cache() { 
    166  
    167         // Close dbm file 
    168         dba_close($this->dba); 
    169  
    170         // Create new dbm file 
    171         $this->dba = dba_open($this->dbm_filename, 'n', $this->cache_type); 
    172  
    173         if (!$this->dba) { 
    174             die('failed to clear cache/recreate dbm file: ' . $this->dbm_filename); 
    175         } 
    176  
    177         // Insert getID3 version number 
    178         dba_insert(getid3::VERSION, getid3::VERSION, $this->dba); 
    179  
    180         // Reregister shutdown function 
    181         register_shutdown_function(array($this, '__destruct')); 
    182     } 
    183  
    184  
    185  
    186     // public: analyze file 
    187     public function Analyze($filename) { 
    188  
    189         if (file_exists($filename)) { 
    190  
    191             // Calc key     filename::mod_time::size    - should be unique 
    192             $key = $filename . '::' . filemtime($filename) . '::' . filesize($filename); 
    193  
    194             // Loopup key 
    195             $result = dba_fetch($key, $this->dba); 
    196  
    197             // Hit 
    198             if ($result !== false) { 
    199                 return unserialize($result); 
    200             } 
    201         } 
    202  
    203         // Miss 
    204         $result = parent::Analyze($filename); 
    205  
    206         // Save result 
    207         if (file_exists($filename)) { 
    208             dba_insert($key, serialize($result), $this->dba); 
    209         } 
    210  
    211         return $result; 
    212     } 
     75        // public: constructor - see top of this file for cache type and cache_options 
     76        function getID3_cached_dbm($cache_type, $dbm_filename, $lock_filename) { 
     77 
     78                // Check for dba extension 
     79                if (!extension_loaded('dba')) { 
     80                        die('PHP is not compiled with dba support, required to use DBM style cache.'); 
     81                } 
     82 
     83                // Check for specific dba driver 
     84                if (function_exists('dba_handlers')) {  // PHP 4.3.0+ 
     85                        if (!in_array('db3', dba_handlers())) { 
     86                                die('PHP is not compiled --with '.$cache_type.' support, required to use DBM style cache.'); 
     87                        } 
     88                } 
     89                else { // PHP <= 4.2.3 
     90                        ob_start(); // nasty, buy the only way to check... 
     91                        phpinfo(); 
     92                        $contents = ob_get_contents(); 
     93                        ob_end_clean(); 
     94                        if (!strstr($contents, $cache_type)) { 
     95                                die('PHP is not compiled --with '.$cache_type.' support, required to use DBM style cache.'); 
     96                        } 
     97                } 
     98 
     99                // Create lock file if needed 
     100                if (!file_exists($lock_filename)) { 
     101                        if (!touch($lock_filename)) { 
     102                                die('failed to create lock file: ' . $lock_filename); 
     103                        } 
     104                } 
     105 
     106                // Open lock file for writing 
     107                if (!is_writeable($lock_filename)) { 
     108                        die('lock file: ' . $lock_filename . ' is not writable'); 
     109                } 
     110                $this->lock = fopen($lock_filename, 'w'); 
     111 
     112                // Acquire exclusive write lock to lock file 
     113                flock($this->lock, LOCK_EX); 
     114 
     115                // Create dbm-file if needed 
     116                if (!file_exists($dbm_filename)) { 
     117                        if (!touch($dbm_filename)) { 
     118                                die('failed to create dbm file: ' . $dbm_filename); 
     119                        } 
     120                } 
     121 
     122                // Try to open dbm file for writing 
     123                $this->dba = @dba_open($dbm_filename, 'w', $cache_type); 
     124                if (!$this->dba) { 
     125 
     126                        // Failed - create new dbm file 
     127                        $this->dba = dba_open($dbm_filename, 'n', $cache_type); 
     128 
     129                        if (!$this->dba) { 
     130                                die('failed to create dbm file: ' . $dbm_filename); 
     131                        } 
     132 
     133                        // Insert getID3 version number 
     134                        dba_insert(GETID3_VERSION, GETID3_VERSION, $this->dba); 
     135                } 
     136 
     137                // Init misc values 
     138                $this->cache_type   = $cache_type; 
     139                $this->dbm_filename = $dbm_filename; 
     140 
     141                // Register destructor 
     142                register_shutdown_function(array($this, '__destruct')); 
     143 
     144                // Check version number and clear cache if changed 
     145                if (dba_fetch(GETID3_VERSION, $this->dba) != GETID3_VERSION) { 
     146                        $this->clear_cache(); 
     147                } 
     148 
     149                parent::getID3(); 
     150        } 
     151 
     152 
     153 
     154        // public: destuctor 
     155        function __destruct() { 
     156 
     157                // Close dbm file 
     158                @dba_close($this->dba); 
     159 
     160                // Release exclusive lock 
     161                @flock($this->lock, LOCK_UN); 
     162 
     163                // Close lock file 
     164                @fclose($this->lock); 
     165        } 
     166 
     167 
     168 
     169        // public: clear cache 
     170        function clear_cache() { 
     171 
     172                // Close dbm file 
     173                dba_close($this->dba); 
     174 
     175                // Create new dbm file 
     176                $this->dba = dba_open($this->dbm_filename, 'n', $this->cache_type); 
     177 
     178                if (!$this->dba) { 
     179                        die('failed to clear cache/recreate dbm file: ' . $this->dbm_filename); 
     180                } 
     181 
     182                // Insert getID3 version number 
     183                dba_insert(GETID3_VERSION, GETID3_VERSION, $this->dba); 
     184 
     185                // Reregister shutdown function 
     186                register_shutdown_function(array($this, '__destruct')); 
     187        } 
     188 
     189 
     190 
     191        // public: analyze file 
     192        function analyze($filename) { 
     193 
     194                if (file_exists($filename)) { 
     195 
     196                        // Calc key     filename::mod_time::size    - should be unique 
     197                        $key = $filename . '::' . filemtime($filename) . '::' . filesize($filename); 
     198 
     199                        // Loopup key 
     200                        $result = dba_fetch($key, $this->dba); 
     201 
     202                        // Hit 
     203                        if ($result !== false) { 
     204                                return unserialize($result); 
     205                        } 
     206                } 
     207 
     208                // Miss 
     209                $result = parent::analyze($filename); 
     210 
     211                // Save result 
     212                if (file_exists($filename)) { 
     213                        dba_insert($key, serialize($result), $this->dba); 
     214                } 
     215 
     216                return $result; 
     217        } 
    213218 
    214219} 
  • extensions/charlies_content/getid3/getid3/extension.cache.mysql.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | extension.cache.mysql.php                                            | 
    18 // | MySQL Cache Extension.                                               | 
    19 // | dependencies: getid3.                                                | 
    20 // +----------------------------------------------------------------------+ 
    21 // 
    22 // $Id$ 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7//                                                             // 
     8// extension.cache.mysql.php - part of getID3()                // 
     9// Please see readme.txt for more information                  // 
     10//                                                            /// 
     11///////////////////////////////////////////////////////////////// 
     12//                                                             // 
     13// This extension written by Allan Hansen <ahØartemis*dk>      // 
     14//                                                            /// 
     15///////////////////////////////////////////////////////////////// 
    2316 
    2417 
     
    3225* 
    3326*       require_once 'getid3/getid3.php'; 
    34 *       $getid3 = new getid3; 
    35 *       $getid3->encoding = 'UTF-8'; 
    36 *       try {  
    37 *           $info1 = $getid3->Analyse('file1.flac'); 
    38 *           $info2 = $getid3->Analyse('file2.wv'); 
    39 *           .... 
     27*       $getID3 = new getID3; 
     28*       $getID3->encoding = 'UTF-8'; 
     29*       $info1 = $getID3->analyze('file1.flac'); 
     30*       $info2 = $getID3->analyze('file2.wv'); 
    4031* 
    4132*    getID3_cached usage: 
     
    4334*       require_once 'getid3/getid3.php'; 
    4435*       require_once 'getid3/getid3/extension.cache.mysql.php'; 
    45 *       $getid3 = new getid3_cached_mysql('localhost', 'database', 'username', 'password'); 
    46 *       $getid3->encoding = 'UTF-8'; 
    47 *       try { 
    48 *           $info1 = $getid3->analyse('file1.flac'); 
    49 *           $info2 = $getid3->analyse('file2.wv'); 
    50 *           ... 
     36*       $getID3 = new getID3_cached_mysql('localhost', 'database', 
     37*                                         'username', 'password'); 
     38*       $getID3->encoding = 'UTF-8'; 
     39*       $info1 = $getID3->analyze('file1.flac'); 
     40*       $info2 = $getID3->analyze('file2.wv'); 
    5141* 
    5242* 
     
    8070 
    8171 
    82 class getid3_cached_mysql extends getID3 
     72class getID3_cached_mysql extends getID3 
    8373{ 
    8474 
    85     private $cursor; 
    86     private $connection; 
     75        // private vars 
     76        var $cursor; 
     77        var $connection; 
    8778 
    8879 
    89     public function __construct($host, $database, $username, $password) { 
     80        // public: constructor - see top of this file for cache type and cache_options 
     81        function getID3_cached_mysql($host, $database, $username, $password) { 
    9082 
    91         // Check for mysql support 
    92         if (!function_exists('mysql_pconnect')) { 
    93             throw new getid3_exception('PHP not compiled with mysql support.'); 
    94         } 
     83                // Check for mysql support 
     84                if (!function_exists('mysql_pconnect')) { 
     85                        die('PHP not compiled with mysql support.'); 
     86                } 
    9587 
    96         // Connect to database 
    97         $this->connection = @mysql_pconnect($host, $username, $password); 
    98         if (!$this->connection) { 
    99             throw new getid3_exception('mysql_pconnect() failed - check permissions and spelling.'); 
    100         } 
     88                // Connect to database 
     89                $this->connection = mysql_pconnect($host, $username, $password); 
     90                if (!$this->connection) { 
     91                        die('mysql_pconnect() failed - check permissions and spelling.'); 
     92                } 
    10193 
    102         // Select database 
    103         if (!@mysql_select_db($database, $this->connection)) { 
    104             throw new getid3_exception('Cannot use database '.$database); 
    105         } 
     94                // Select database 
     95                if (!mysql_select_db($database, $this->connection)) { 
     96                        die('Cannot use database '.$database); 
     97                } 
    10698 
    107         // Create cache table if not exists 
    108         $this->create_table(); 
     99                // Create cache table if not exists 
     100                $this->create_table(); 
    109101 
    110         // Check version number and clear cache if changed 
    111         $this->cursor = mysql_query("SELECT `value` FROM `getid3_cache` WHERE (`filename` = '".getid3::VERSION."') AND (`filesize` = '-1') AND (`filetime` = '-1') AND (`analyzetime` = '-1')", $this->connection); 
    112         list($version) = @mysql_fetch_array($this->cursor); 
    113         if ($version != getid3::VERSION) { 
    114             $this->clear_cache(); 
    115         } 
     102                // Check version number and clear cache if changed 
     103                $this->cursor = mysql_query("SELECT `value` FROM `getid3_cache` WHERE (`filename` = '".GETID3_VERSION."') AND (`filesize` = '-1') AND (`filetime` = '-1') AND (`analyzetime` = '-1')", $this->connection); 
     104                list($version) = @mysql_fetch_array($this->cursor); 
     105                if ($version != GETID3_VERSION) { 
     106                        $this->clear_cache(); 
     107                } 
    116108 
    117         parent::__construct(); 
    118     } 
     109                parent::getID3(); 
     110        } 
    119111 
    120112 
    121113 
    122     public function clear_cache() { 
     114        // public: clear cache 
     115        function clear_cache() { 
    123116 
    124         $this->cursor = mysql_query("DELETE FROM `getid3_cache`", $this->connection); 
    125         $this->cursor = mysql_query("INSERT INTO `getid3_cache` VALUES ('".getid3::VERSION."', -1, -1, -1, '".getid3::VERSION."')", $this->connection); 
    126     } 
     117                $this->cursor = mysql_query("DELETE FROM `getid3_cache`", $this->connection); 
     118                $this->cursor = mysql_query("INSERT INTO `getid3_cache` VALUES ('".GETID3_VERSION."', -1, -1, -1, '".GETID3_VERSION."')", $this->connection); 
     119        } 
    127120 
    128121 
    129122 
    130     public function Analyze($filename) { 
     123        // public: analyze file 
     124        function analyze($filename) { 
    131125 
    132         if (file_exists($filename)) { 
     126                if (file_exists($filename)) { 
    133127 
    134             // Short-hands 
    135             $filetime = filemtime($filename); 
    136             $filesize = filesize($filename); 
    137             $filenam2 = mysql_escape_string($filename); 
     128                        // Short-hands 
     129                        $filetime = filemtime($filename); 
     130                        $filesize = filesize($filename); 
     131                        $filenam2 = mysql_escape_string($filename); 
    138132 
    139             // Loopup file 
    140             $this->cursor = mysql_query("SELECT `value` FROM `getid3_cache` WHERE (`filename`='".$filenam2."') AND (`filesize`='".$filesize."') AND (`filetime`='".$filetime."')", $this->connection); 
    141             list($result) = @mysql_fetch_array($this->cursor); 
     133                        // Loopup file 
     134                        $this->cursor = mysql_query("SELECT `value` FROM `getid3_cache` WHERE (`filename`='".$filenam2."') AND (`filesize`='".$filesize."') AND (`filetime`='".$filetime."')", $this->connection); 
     135                        list($result) = @mysql_fetch_array($this->cursor); 
    142136 
    143             // Hit 
    144             if ($result) { 
    145                 return unserialize($result); 
    146             } 
    147         } 
     137                        // Hit 
     138                        if ($result) { 
     139                                return unserialize($result); 
     140                        } 
     141                } 
    148142 
    149         // Miss 
    150         $result = parent::Analyze($filename); 
     143                // Miss 
     144                $result = parent::analyze($filename); 
    151145 
    152         // Save result 
    153         if (file_exists($filename)) { 
    154             $res2 = mysql_escape_string(serialize($result)); 
    155             $this->cursor = mysql_query("INSERT INTO `getid3_cache` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES ('".$filenam2."', '".$filesize."', '".$filetime."', '".time()."', '".$res2."')", $this->connection); 
    156         } 
    157         return $result; 
    158     } 
     146                // Save result 
     147                if (file_exists($filename)) { 
     148                        $res2 = mysql_escape_string(serialize($result)); 
     149                        $this->cursor = mysql_query("INSERT INTO `getid3_cache` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES ('".$filenam2."', '".$filesize."', '".$filetime."', '".time()."', '".$res2."')", $this->connection); 
     150                } 
     151                return $result; 
     152        } 
    159153 
    160154 
    161155 
    162     // (re)create sql table 
    163     private function create_table($drop = false) { 
     156        // private: (re)create sql table 
     157        function create_table($drop = false) { 
    164158 
    165         $this->cursor = mysql_query("CREATE TABLE IF NOT EXISTS `getid3_cache` ( 
    166             `filename` VARCHAR(255) NOT NULL DEFAULT '', 
    167             `filesize` INT(11) NOT NULL DEFAULT '0', 
    168             `filetime` INT(11) NOT NULL DEFAULT '0', 
    169             `analyzetime` INT(11) NOT NULL DEFAULT '0', 
    170             `value` TEXT NOT NULL, 
    171             PRIMARY KEY (`filename`,`filesize`,`filetime`)) TYPE=MyISAM", $this->connection); 
    172         echo mysql_error($this->connection); 
    173     } 
     159                $this->cursor = mysql_query("CREATE TABLE IF NOT EXISTS `getid3_cache` ( 
     160                        `filename` VARCHAR(255) NOT NULL DEFAULT '', 
     161                        `filesize` INT(11) NOT NULL DEFAULT '0', 
     162                        `filetime` INT(11) NOT NULL DEFAULT '0', 
     163                        `analyzetime` INT(11) NOT NULL DEFAULT '0', 
     164                        `value` TEXT NOT NULL, 
     165                        PRIMARY KEY (`filename`,`filesize`,`filetime`)) TYPE=MyISAM", $this->connection); 
     166                echo mysql_error($this->connection); 
     167        } 
    174168} 
    175169 
  • extensions/charlies_content/getid3/getid3/getid3.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | getid3.php                                                           | 
    18 // | Main getID3() file.                                                  | 
    19 // | dependencies: modules.                                               | 
    20 // +----------------------------------------------------------------------+ 
    21 // 
    22 // $Id$ 
    23  
    24  
    25 class getid3 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7//                                                             // 
     8// Please see readme.txt for more information                  // 
     9//                                                            /// 
     10///////////////////////////////////////////////////////////////// 
     11 
     12// Defines 
     13define('GETID3_VERSION', '1.7.9-20090308'); 
     14define('GETID3_FREAD_BUFFER_SIZE', 16384); // read buffer size in bytes 
     15 
     16 
     17 
     18class getID3 
    2619{ 
    27     //// Settings Section - do NOT modify this file - change setting after newing getid3! 
    28  
    29     // Encoding 
    30     public $encoding                 = 'ISO-8859-1';      // CASE SENSITIVE! - i.e. (must be supported by iconv() - see http://www.gnu.org/software/libiconv/).  Examples:  ISO-8859-1  UTF-8  UTF-16  UTF-16BE. 
    31     public $encoding_id3v1           = 'ISO-8859-1';      // Override SPECIFICATION encoding for broken ID3v1 tags caused by bad tag programs. Examples: 'EUC-CN' for "Chinese MP3s" and 'CP1251' for "Cyrillic". 
    32     public $encoding_id3v2           = 'ISO-8859-1';      // Override ISO-8859-1 encoding for broken ID3v2 tags caused by BRAINDEAD tag programs that writes system codepage as 'ISO-8859-1' instead of UTF-8. 
    33  
    34     // Tags - disable for speed 
    35     public $option_tag_id3v1         = true;              // Read and process ID3v1 tags. 
    36     public $option_tag_id3v2         = true;              // Read and process ID3v2 tags. 
    37     public $option_tag_lyrics3       = true;              // Read and process Lyrics3 tags. 
    38     public $option_tag_apetag        = true;              // Read and process APE tags. 
    39  
    40     // Misc calucations - disable for speed 
    41     public $option_analyze           = true;              // Analyze file - disable if you only need to detect file format. 
    42     public $option_accurate_results  = true;              // Disable to greatly speed up parsing of some file formats at the cost of accuracy. 
    43     public $option_tags_process      = true;              // Copy tags to root key 'tags' and 'comments' and encode to $this->encoding. 
    44     public $option_tags_images       = false;             // Scan tags for binary image data - ID3v2 and vorbiscomments only. 
    45     public $option_extra_info        = true;              // Calculate/return additional info such as bitrate, channelmode etc. 
    46     public $option_max_2gb_check     = false;             // Check whether file is larger than 2 Gb and thus not supported by PHP. 
    47  
    48     // Misc data hashes - slow - require hash module 
    49     public $option_md5_data          = false;             // Get MD5 sum of data part - slow. 
    50     public $option_md5_data_source   = false;             // Use MD5 of source file if available - only FLAC, MAC, OptimFROG and Wavpack4. 
    51     public $option_sha1_data         = false;             // Get SHA1 sum of data part - slow. 
    52  
    53     // Public variables 
    54     public $filename;                                     // Filename of file being analysed. 
    55     public $fp;                                           // Filepointer to file being analysed. 
    56     public $info;                                         // Result array. 
    57  
    58     // Protected variables 
    59     protected $include_path;                              // getid3 include path. 
    60     protected $warnings = array (); 
    61     protected $iconv_present; 
    62  
    63     // Class constants 
    64     const VERSION           = '2.0.0b4'; 
    65     const FREAD_BUFFER_SIZE = 16384;                      // Read buffer size in bytes. 
    66     const ICONV_TEST_STRING = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„ 
    67 †‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'; 
    68  
    69  
    70  
    71     // Constructor - check PHP enviroment and load library. 
    72     public function __construct() { 
    73  
    74         // Static varibles - no need to recalc every time we new getid3. 
    75         static $include_path; 
    76         static $iconv_present; 
    77  
    78  
    79         static $initialized; 
    80         if ($initialized) { 
    81  
    82             // Import static variables 
    83             $this->include_path  = $include_path; 
    84             $this->iconv_present = $iconv_present; 
    85  
    86             // Run init checks only on first instance. 
    87             return; 
    88         } 
    89  
    90         // Get include_path 
    91         $this->include_path = $include_path = dirname(__FILE__) . '/'; 
    92  
    93         // Check for presence of iconv() and make sure it works (simpel test only). 
    94         if (function_exists('iconv') && @iconv('UTF-16LE', 'ISO-8859-1', @iconv('ISO-8859-1', 'UTF-16LE', getid3::ICONV_TEST_STRING)) == getid3::ICONV_TEST_STRING) { 
    95             $this->iconv_present = $iconv_present = true; 
    96         } 
    97  
    98         // iconv() not present - load replacement module. 
    99         else { 
    100             $this->include_module('lib.iconv_replacement'); 
    101             $this->iconv_present = $iconv_present = false; 
    102         } 
    103  
    104  
    105         // Require magic_quotes_runtime off 
    106         if (get_magic_quotes_runtime()) { 
    107             throw new getid3_exception('magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'); 
    108         } 
    109  
    110  
    111         // Check memory limit. 
    112         $memory_limit = ini_get('memory_limit'); 
    113         if (eregi('([0-9]+)M', $memory_limit, $matches)) { 
    114             // could be stored as "16M" rather than 16777216 for example 
    115             $memory_limit = $matches[1] * 1048576; 
    116         } 
    117         if ($memory_limit <= 0) { 
    118             // Should not happen. 
    119         } elseif ($memory_limit <= 4194304) { 
    120             $this->warning('[SERIOUS] PHP has less than 4 Mb available memory and will very likely run out. Increase memory_limit in php.ini.'); 
    121         } elseif ($memory_limit <= 12582912) { 
    122             $this->warning('PHP has less than 12 Mb available memory and might run out if all modules are loaded. Increase memory_limit in php.ini if needed.'); 
    123         } 
    124  
    125  
    126         // Check safe_mode off 
    127         if ((bool)ini_get('safe_mode')) { 
    128             $this->warning('Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbis/flac tag writing disabled.'); 
    129         } 
    130  
    131         $initialized = true; 
    132     } 
    133  
    134  
    135  
    136     // Analyze file by name 
    137     public function Analyze($filename) { 
    138  
    139         // Init and save values 
    140         $this->filename = $filename; 
    141         $this->warnings = array (); 
    142  
    143         // Init result array and set parameters 
    144         $this->info = array (); 
    145         $this->info['GETID3_VERSION'] = getid3::VERSION; 
    146  
    147         // Remote files not supported 
    148         if (preg_match('/^(ht|f)tp:\/\//', $filename)) { 
    149             throw new getid3_exception('Remote files are not supported - please copy the file locally first.'); 
    150         } 
    151  
    152         // Open local file 
    153         if (!$this->fp = @fopen($filename, 'rb')) { 
    154             throw new getid3_exception('Could not open file "'.$filename.'"'); 
    155         } 
    156  
    157         // Set filesize related parameters 
    158         $this->info['filesize']     = filesize($filename); 
    159         $this->info['avdataoffset'] = 0; 
    160         $this->info['avdataend']    = $this->info['filesize']; 
    161  
    162         // Option_max_2gb_check 
    163         if ($this->option_max_2gb_check) { 
    164             // PHP doesn't support integers larger than 31-bit (~2GB) 
    165             // filesize() simply returns (filesize % (pow(2, 32)), no matter the actual filesize 
    166             // ftell() returns 0 if seeking to the end is beyond the range of unsigned integer 
    167             fseek($this->fp, 0, SEEK_END); 
    168             if ((($this->info['filesize'] != 0) && (ftell($this->fp) == 0)) || 
    169                 ($this->info['filesize'] < 0) || 
    170                 (ftell($this->fp) < 0)) { 
    171                     unset($this->info['filesize']); 
    172                     fclose($this->fp); 
    173                     throw new getid3_exception('File is most likely larger than 2GB and is not supported by PHP.'); 
    174             } 
    175         } 
    176  
    177  
    178         // ID3v2 detection (NOT parsing) done to make fileformat easier. 
    179         if (!$this->option_tag_id3v2) { 
    180  
    181             fseek($this->fp, 0, SEEK_SET); 
    182             $header = fread($this->fp, 10); 
    183             if (substr($header, 0, 3) == 'ID3'  &&  strlen($header) == 10) { 
    184                 $this->info['id3v2']['header']        = true; 
    185                 $this->info['id3v2']['majorversion']  = ord($header{3}); 
    186                 $this->info['id3v2']['minorversion']  = ord($header{4}); 
    187                 $this->info['avdataoffset']          += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length 
    188             } 
    189         } 
    190  
    191  
    192         // Handle tags 
    193         foreach (array ("id3v2", "id3v1", "apetag", "lyrics3") as $tag_name) { 
    194  
    195             $option_tag = 'option_tag_' . $tag_name; 
    196             if ($this->$option_tag) { 
    197                 $this->include_module('tag.'.$tag_name); 
    198                 try { 
    199                     $tag_class = 'getid3_' . $tag_name; 
    200                     $tag = new $tag_class($this); 
    201                     $tag->Analyze(); 
    202                 } 
    203                 catch (getid3_exception $e) { 
    204                     throw $e; 
    205                 } 
    206             } 
    207         } 
    208  
    209  
    210  
    211         //// Determine file format by magic bytes in file header. 
    212  
    213         // Read 32 kb file data 
    214         fseek($this->fp, $this->info['avdataoffset'], SEEK_SET); 
    215         $filedata = fread($this->fp, 32774); 
    216  
    217         // Get huge FileFormatArray 
    218         $file_format_array = getid3::GetFileFormatArray(); 
    219  
    220         // Identify file format - loop through $format_info and detect with reg expr 
    221         foreach ($file_format_array as $name => $info) { 
    222  
    223             if (preg_match('/'.$info['pattern'].'/s', $filedata)) {                         // The /s switch on preg_match() forces preg_match() NOT to treat newline (0x0A) characters as special chars but do a binary match 
    224  
    225                 // Format detected but not supported 
    226                 if (!@$info['module'] || !@$info['group']) { 
    227                     fclose($this->fp); 
    228                     $this->info['fileformat'] = $name; 
    229                     $this->info['mime_type']  = $info['mime_type']; 
    230                     $this->warning('Format only detected. Parsing not available yet.'); 
    231                     $this->info['warning'] = $this->warnings; 
    232                     return $this->info; 
    233                 } 
    234  
    235                 $determined_format = $info;  // copy $info deleted by foreach() 
    236                 continue; 
    237             } 
    238         } 
    239  
    240         // Unable to determine file format 
    241         if (!@$determined_format) { 
    242  
    243             // Too many mp3 encoders on the market put gabage in front of mpeg files 
    244             // use assume format on these if format detection failed 
    245             if (preg_match('/\.mp[123a]$/i', $filename)) { 
    246                 $determined_format = $file_format_array['mp3']; 
    247             } 
    248  
    249             else { 
    250                 fclose($this->fp); 
    251                 throw new getid3_exception('Unable to determine file format'); 
    252             } 
    253         } 
    254  
    255         // Free memory 
    256         unset($file_format_array); 
    257  
    258         // Check for illegal ID3 tags 
    259         if (@$determined_format['fail_id3'] && (@$this->info['id3v1'] || @$this->info['id3v2'])) { 
    260             if ($determined_format['fail_id3'] === 'ERROR') { 
    261                 fclose($this->fp); 
    262                 throw new getid3_exception('ID3 tags not allowed on this file type.'); 
    263             } 
    264             elseif ($determined_format['fail_id3'] === 'WARNING') { 
    265                 @$this->info['id3v1'] and $this->warning('ID3v1 tags not allowed on this file type.'); 
    266                 @$this->info['id3v2'] and $this->warning('ID3v2 tags not allowed on this file type.'); 
    267             } 
    268         } 
    269  
    270         // Check for illegal APE tags 
    271         if (@$determined_format['fail_ape'] && @$this->info['tags']['ape']) { 
    272             if ($determined_format['fail_ape'] === 'ERROR') { 
    273                 fclose($this->fp); 
    274                 throw new getid3_exception('APE tags not allowed on this file type.'); 
    275             } elseif ($determined_format['fail_ape'] === 'WARNING') { 
    276                 $this->warning('APE tags not allowed on this file type.'); 
    277             } 
    278         } 
    279  
    280  
    281         // Set mime type 
    282         $this->info['mime_type'] = $determined_format['mime_type']; 
    283  
    284         // Calc module file name 
    285         $determined_format['include'] = 'module.'.$determined_format['group'].'.'.$determined_format['module'].'.php'; 
    286  
    287         // Supported format signature pattern detected, but module deleted. 
    288         if (!file_exists($this->include_path.$determined_format['include'])) { 
    289             fclose($this->fp); 
    290             throw new getid3_exception('Format not supported, module, '.$determined_format['include'].', was removed.'); 
    291         } 
    292  
    293         // Include module 
    294         $this->include_module($determined_format['group'].'.'.$determined_format['module']); 
    295  
    296         // Instantiate module class and analyze 
    297         $class_name = 'getid3_'.$determined_format['module']; 
    298         if (!class_exists($class_name)) { 
    299             throw new getid3_exception('Format not supported, module, '.$determined_format['include'].', is corrupt.'); 
    300         } 
    301         $class = new $class_name($this); 
    302  
    303         try { 
    304              $this->option_analyze and $class->Analyze(); 
    305             } 
    306         catch (getid3_exception $e) { 
    307             throw $e; 
    308         } 
    309         catch (Exception $e) { 
    310             throw new getid3_exception('Corrupt file.'); 
    311         } 
    312  
    313         // Close file 
    314         fclose($this->fp); 
    315  
    316         // Optional - Process all tags - copy to 'tags' and convert charsets 
    317         if ($this->option_tags_process) { 
    318             $this->HandleAllTags(); 
    319         } 
    320  
    321  
    322         //// Optional - perform more calculations 
    323         if ($this->option_extra_info) { 
    324  
    325             // Set channelmode on audio 
    326             if (@$this->info['audio']['channels'] == '1') { 
    327                 $this->info['audio']['channelmode'] = 'mono'; 
    328             } elseif (@$this->info['audio']['channels'] == '2') { 
    329                 $this->info['audio']['channelmode'] = 'stereo'; 
    330             } 
    331  
    332             // Calculate combined bitrate - audio + video 
    333             $combined_bitrate  = 0; 
    334             $combined_bitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0); 
    335             $combined_bitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0); 
    336             if (($combined_bitrate > 0) && empty($this->info['bitrate'])) { 
    337                 $this->info['bitrate'] = $combined_bitrate; 
    338             } 
    339             if (!isset($this->info['playtime_seconds']) && !empty($this->info['bitrate'])) { 
    340                 $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate']; 
    341             } 
    342  
    343             // Set playtime string 
    344             if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { 
    345                 $this->info['playtime_string'] =  floor(round($this->info['playtime_seconds']) / 60) . ':' . str_pad(floor(round($this->info['playtime_seconds']) % 60), 2, 0, STR_PAD_LEFT);; 
    346             } 
    347  
    348  
    349             // CalculateCompressionRatioVideo() { 
    350             if (@$this->info['video'] && @$this->info['video']['resolution_x'] && @$this->info['video']['resolution_y'] && @$this->info['video']['bits_per_sample']) { 
    351  
    352                 // From static image formats 
    353                 if (in_array($this->info['video']['dataformat'], array ('bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff'))) { 
    354                     $frame_rate         = 1; 
    355                     $bitrate_compressed = $this->info['filesize'] * 8; 
    356                 } 
    357  
    358                 // From video formats 
    359                 else { 
    360                     $frame_rate         = @$this->info['video']['frame_rate']; 
    361                     $bitrate_compressed = @$this->info['video']['bitrate']; 
    362                 } 
    363  
    364                 if ($frame_rate && $bitrate_compressed) { 
    365                     $this->info['video']['compression_ratio'] = $bitrate_compressed / ($this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $frame_rate); 
    366                 } 
    367             } 
    368  
    369  
    370             // CalculateCompressionRatioAudio() { 
    371             if (@$this->info['audio']['bitrate'] && @$this->info['audio']['channels'] && @$this->info['audio']['sample_rate']) { 
    372                 $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (@$this->info['audio']['bits_per_sample'] ? $this->info['audio']['bits_per_sample'] : 16)); 
    373             } 
    374  
    375             if (@$this->info['audio']['streams']) { 
    376                 foreach ($this->info['audio']['streams'] as $stream_number => $stream_data) { 
    377                     if (@$stream_data['bitrate'] && @$stream_data['channels'] && @$stream_data['sample_rate']) { 
    378                         $this->info['audio']['streams'][$stream_number]['compression_ratio'] = $stream_data['bitrate'] / ($stream_data['channels'] * $stream_data['sample_rate'] * (@$stream_data['bits_per_sample'] ? $stream_data['bits_per_sample'] : 16)); 
    379                     } 
    380                 } 
    381             } 
    382  
    383  
    384             // CalculateReplayGain() { 
    385             if (@$this->info['replay_gain']) { 
    386                 if (!@$this->info['replay_gain']['reference_volume']) { 
    387                      $this->info['replay_gain']['reference_volume'] = 89; 
    388                 } 
    389                 if (isset($this->info['replay_gain']['track']['adjustment'])) { 
    390                     $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; 
    391                 } 
    392                 if (isset($this->info['replay_gain']['album']['adjustment'])) { 
    393                     $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment']; 
    394                 } 
    395  
    396                 if (isset($this->info['replay_gain']['track']['peak'])) { 
    397                     $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - 20 * log10($this->info['replay_gain']['track']['peak']); 
    398                 } 
    399                 if (isset($this->info['replay_gain']['album']['peak'])) { 
    400                     $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - 20 * log10($this->info['replay_gain']['album']['peak']); 
    401                 } 
    402             } 
    403  
    404  
    405             // ProcessAudioStreams() { 
    406             if (@!$this->info['audio']['streams'] && (@$this->info['audio']['bitrate'] || @$this->info['audio']['channels'] || @$this->info['audio']['sample_rate'])) { 
    407                   foreach ($this->info['audio'] as $key => $value) { 
    408                     if ($key != 'streams') { 
    409                         $this->info['audio']['streams'][0][$key] = $value; 
    410                     } 
    411                 } 
    412             } 
    413         } 
    414  
    415  
    416         // Get the md5/sha1sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags. 
    417         if ($this->option_md5_data || $this->option_sha1_data) { 
    418  
    419             // Load data-hash library if needed 
    420             $this->include_module('lib.data_hash'); 
    421  
    422             if ($this->option_sha1_data) { 
    423                 new getid3_lib_data_hash($this, 'sha1'); 
    424             } 
    425  
    426             if ($this->option_md5_data) { 
    427  
    428                 // no md5_data_source or option disabled -- md5_data_source supported by FLAC, MAC, OptimFROG, Wavpack4 
    429                 if (!$this->option_md5_data_source || !@$this->info['md5_data_source']) { 
    430                     new getid3_lib_data_hash($this, 'md5'); 
    431                 } 
    432  
    433                 // copy md5_data_source to md5_data if option set to true 
    434                 elseif ($this->option_md5_data_source && @$this->info['md5_data_source']) { 
    435                     $this->info['md5_data'] = $this->info['md5_data_source']; 
    436                 } 
    437             } 
    438         } 
    439  
    440         // Set warnings 
    441         if ($this->warnings) { 
    442             $this->info['warning'] = $this->warnings; 
    443         } 
    444  
    445         // Return result 
    446         return $this->info; 
    447     } 
    448  
    449  
    450  
    451     // Return array of warnings 
    452     public function warnings() { 
    453  
    454         return $this->warnings; 
    455     } 
    456  
    457  
    458  
    459     // Add warning(s) to $this->warnings[] 
    460     public function warning($message) { 
    461  
    462         if (is_array($message)) { 
    463             $this->warnings = array_merge($this->warnings, $message); 
    464         } 
    465         else { 
    466             $this->warnings[] = $message; 
    467         } 
    468     } 
    469  
    470  
    471  
    472     //  Clear all warnings when cloning 
    473     public function __clone() { 
    474  
    475         $this->warnings = array (); 
    476  
    477         // Copy info array, otherwise it will be a reference. 
    478         $temp = $this->info; 
    479         unset($this->info); 
    480         $this->info = $temp; 
    481     } 
    482  
    483  
    484  
    485     // Convert string between charsets -- iconv() wrapper 
    486     public function iconv($in_charset, $out_charset, $string, $drop01 = false) { 
    487  
    488         if ($drop01 && ($string === "\x00" || $string === "\x01")) { 
    489             return ''; 
    490         } 
    491  
    492  
    493         if (!$this->iconv_present) { 
    494             return getid3_iconv_replacement::iconv($in_charset, $out_charset, $string); 
    495         } 
    496  
    497  
    498         // iconv() present 
    499         if ($result = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) { 
    500  
    501             if ($out_charset == 'ISO-8859-1') { 
    502                 return rtrim($result, "\x00"); 
    503             } 
    504             return $result; 
    505         } 
    506  
    507         $this->warning('iconv() was unable to convert the string: "' . $string . '" from ' . $in_charset . ' to ' . $out_charset); 
    508         return $string; 
    509     } 
    510  
    511  
    512  
    513     public function include_module($name) { 
    514  
    515         if (!file_exists($this->include_path.'module.'.$name.'.php')) { 
    516             throw new getid3_exception('Required module.'.$name.'.php is missing.'); 
    517         } 
    518  
    519         include_once($this->include_path.'module.'.$name.'.php'); 
    520     } 
    521  
    522  
    523  
    524     public function include_module_optional($name) { 
    525  
    526         if (!file_exists($this->include_path.'module.'.$name.'.php')) { 
    527             return; 
    528         } 
    529  
    530         include_once($this->include_path.'module.'.$name.'.php'); 
    531         return true; 
    532     } 
    533  
    534  
    535     // Return array containing information about all supported formats 
    536     public static function GetFileFormatArray() { 
    537  
    538         static $format_info = array ( 
    539  
    540                 // Audio formats 
    541  
    542                 // AC-3   - audio      - Dolby AC-3 / Dolby Digital 
    543                 'ac3'  => array ( 
    544                             'pattern'   => '^\x0B\x77', 
    545                             'group'     => 'audio', 
    546                             'module'    => 'ac3', 
    547                             'mime_type' => 'audio/ac3', 
    548                           ), 
    549  
    550                 // AAC  - audio       - Advanced Audio Coding (AAC) - ADIF format 
    551                 'adif' => array ( 
    552                             'pattern'   => '^ADIF', 
    553                             'group'     => 'audio', 
    554                             'module'    => 'aac_adif', 
    555                             'mime_type' => 'application/octet-stream', 
    556                             'fail_ape'  => 'WARNING', 
    557                           ), 
    558  
    559  
    560                 // AAC  - audio       - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3) 
    561                 'adts' => array ( 
    562                             'pattern'   => '^\xFF[\xF0-\xF1\xF8-\xF9]', 
    563                             'group'     => 'audio', 
    564                             'module'    => 'aac_adts', 
    565                             'mime_type' => 'application/octet-stream', 
    566                             'fail_ape'  => 'WARNING', 
    567                           ), 
    568  
    569  
    570                 // AU   - audio       - NeXT/Sun AUdio (AU) 
    571                 'au'   => array ( 
    572                             'pattern'   => '^\.snd', 
    573                             'group'     => 'audio', 
    574                             'module'    => 'au', 
    575                             'mime_type' => 'audio/basic', 
    576                           ), 
    577  
    578                 // AVR  - audio       - Audio Visual Research 
    579                 'avr'  => array ( 
    580                             'pattern'   => '^2BIT', 
    581                             'group'     => 'audio', 
    582                             'module'    => 'avr', 
    583                             'mime_type' => 'application/octet-stream', 
    584                           ), 
    585  
    586                 // BONK - audio       - Bonk v0.9+ 
    587                 'bonk' => array ( 
    588                             'pattern'   => '^\x00(BONK|INFO|META| ID3)', 
    589                             'group'     => 'audio', 
    590                             'module'    => 'bonk', 
    591                             'mime_type' => 'audio/xmms-bonk', 
    592                           ), 
    593  
    594                 // DTS  - audio       - Dolby Theatre System 
     20        // public: Settings 
     21        var $encoding        = 'ISO-8859-1';   // CASE SENSITIVE! - i.e. (must be supported by iconv()) 
     22                                               // Examples:  ISO-8859-1  UTF-8  UTF-16  UTF-16BE 
     23 
     24        var $encoding_id3v1  = 'ISO-8859-1';   // Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' 
     25 
     26        var $tempdir         = '*';            // default '*' should use system temp dir 
     27 
     28        // public: Optional tag checks - disable for speed. 
     29        var $option_tag_id3v1         = true;  // Read and process ID3v1 tags 
     30        var $option_tag_id3v2         = true;  // Read and process ID3v2 tags 
     31        var $option_tag_lyrics3       = true;  // Read and process Lyrics3 tags 
     32        var $option_tag_apetag        = true;  // Read and process APE tags 
     33        var $option_tags_process      = true;  // Copy tags to root key 'tags' and encode to $this->encoding 
     34        var $option_tags_html         = true;  // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities 
     35 
     36        // public: Optional tag/comment calucations 
     37        var $option_extra_info        = true;  // Calculate additional info such as bitrate, channelmode etc 
     38 
     39        // public: Optional calculations 
     40        var $option_md5_data          = false; // Get MD5 sum of data part - slow 
     41        var $option_md5_data_source   = false; // Use MD5 of source file if availble - only FLAC and OptimFROG 
     42        var $option_sha1_data         = false; // Get SHA1 sum of data part - slow 
     43        var $option_max_2gb_check     = true;  // Check whether file is larger than 2 Gb and thus not supported by PHP 
     44 
     45        // private 
     46        var $filename; 
     47 
     48 
     49        // public: constructor 
     50        function getID3() 
     51        { 
     52 
     53                $this->startup_error   = ''; 
     54                $this->startup_warning = ''; 
     55 
     56                // Check for PHP version >= 4.2.0 
     57                if (phpversion() < '4.2.0') { 
     58                    $this->startup_error .= 'getID3() requires PHP v4.2.0 or higher - you are running v'.phpversion(); 
     59                } 
     60 
     61                // Check memory 
     62                $memory_limit = ini_get('memory_limit'); 
     63                if (eregi('([0-9]+)M', $memory_limit, $matches)) { 
     64                        // could be stored as "16M" rather than 16777216 for example 
     65                        $memory_limit = $matches[1] * 1048576; 
     66                } 
     67                if ($memory_limit <= 0) { 
     68                        // memory limits probably disabled 
     69                } elseif ($memory_limit <= 3145728) { 
     70                $this->startup_error .= 'PHP has less than 3MB available memory and will very likely run out. Increase memory_limit in php.ini'; 
     71                } elseif ($memory_limit <= 12582912) { 
     72                $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini'; 
     73                } 
     74 
     75                // Check safe_mode off 
     76                if ((bool) ini_get('safe_mode')) { 
     77                    $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.'); 
     78                } 
     79 
     80 
     81                // define a constant rather than looking up every time it is needed 
     82                if (!defined('GETID3_OS_ISWINDOWS')) { 
     83                        if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { 
     84                                define('GETID3_OS_ISWINDOWS', true); 
     85                        } else { 
     86                                define('GETID3_OS_ISWINDOWS', false); 
     87                        } 
     88                } 
     89 
     90                // Get base path of getID3() - ONCE 
     91                if (!defined('GETID3_INCLUDEPATH')) { 
     92                        foreach (get_included_files() as $key => $val) { 
     93                                if (basename($val) == 'getid3.php') { 
     94                                        define('GETID3_INCLUDEPATH', dirname($val).DIRECTORY_SEPARATOR); 
     95                                        break; 
     96                                } 
     97                        } 
     98                } 
     99 
     100                // Load support library 
     101                if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) { 
     102                        $this->startup_error .= 'getid3.lib.php is missing or corrupt'; 
     103                } 
     104 
     105 
     106                // Needed for Windows only: 
     107                // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC 
     108                //   as well as other helper functions such as head, tail, md5sum, etc 
     109                // IMPORTANT: This path cannot have spaces in it. If neccesary, use the 8dot3 equivalent 
     110                //   ie for "C:/Program Files/Apache/" put "C:/PROGRA~1/APACHE/" 
     111                // IMPORTANT: This path must include the trailing slash 
     112                if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) { 
     113 
     114                        $helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path 
     115 
     116                        if (!is_dir($helperappsdir)) { 
     117                                $this->startup_error .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist'; 
     118                        } elseif (strpos(realpath($helperappsdir), ' ') !== false) { 
     119                                $DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir)); 
     120                                foreach ($DirPieces as $key => $value) { 
     121                                        if ((strpos($value, '.') !== false) && (strpos($value, ' ') === false)) { 
     122                                                if (strpos($value, '.') > 8) { 
     123                                                        $value = substr($value, 0, 6).'~1'; 
     124                                                } 
     125                                        } elseif ((strpos($value, ' ') !== false) || strlen($value) > 8) { 
     126                                                $value = substr($value, 0, 6).'~1'; 
     127                                        } 
     128                                        $DirPieces[$key] = strtoupper($value); 
     129                                } 
     130                                $this->startup_error .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary (on this server that would be something like "'.implode(DIRECTORY_SEPARATOR, $DirPieces).'" - NOTE: this may or may not be the actual 8.3 equivalent of "'.$helperappsdir.'", please double-check). You can run "dir /x" from the commandline to see the correct 8.3-style names.'; 
     131                        } 
     132                        define('GETID3_HELPERAPPSDIR', realpath($helperappsdir).DIRECTORY_SEPARATOR); 
     133                } 
     134 
     135        } 
     136 
     137 
     138        // public: setOption 
     139        function setOption($optArray) { 
     140                if (!is_array($optArray) || empty($optArray)) { 
     141                        return false; 
     142                } 
     143                foreach ($optArray as $opt => $val) { 
     144                        //if (isset($this, $opt) === false) { 
     145                        if (isset($this->$opt) === false) { 
     146                                continue; 
     147                        } 
     148                        $this->$opt = $val; 
     149                } 
     150                return true; 
     151        } 
     152 
     153 
     154        // public: analyze file - replaces GetAllFileInfo() and GetTagOnly() 
     155        function analyze($filename) { 
     156 
     157                if (!empty($this->startup_error)) { 
     158                        return $this->error($this->startup_error); 
     159                } 
     160                if (!empty($this->startup_warning)) { 
     161                        $this->warning($this->startup_warning); 
     162                } 
     163 
     164                // init result array and set parameters 
     165                $this->info = array(); 
     166                $this->info['GETID3_VERSION'] = GETID3_VERSION; 
     167 
     168                // Check encoding/iconv support 
     169                if (!function_exists('iconv') && !in_array($this->encoding, array('ISO-8859-1', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'UTF-16'))) { 
     170                        $errormessage = 'iconv() support is needed for encodings other than ISO-8859-1, UTF-8, UTF-16LE, UTF16-BE, UTF-16. '; 
     171                        if (GETID3_OS_ISWINDOWS) { 
     172                                $errormessage .= 'PHP does not have iconv() support. Please enable php_iconv.dll in php.ini, and copy iconv.dll from c:/php/dlls to c:/windows/system32'; 
     173                        } else { 
     174                                $errormessage .= 'PHP is not compiled with iconv() support. Please recompile with the --with-iconv switch'; 
     175                        } 
     176                return $this->error($errormessage); 
     177                } 
     178 
     179                // Disable magic_quotes_runtime, if neccesary 
     180                $old_magic_quotes_runtime = get_magic_quotes_runtime(); // store current setting of magic_quotes_runtime 
     181                if ($old_magic_quotes_runtime) { 
     182                        set_magic_quotes_runtime(0);                        // turn off magic_quotes_runtime 
     183                        if (get_magic_quotes_runtime()) { 
     184                                return $this->error('Could not disable magic_quotes_runtime - getID3() cannot work properly with this setting enabled'); 
     185                        } 
     186                } 
     187 
     188                // remote files not supported 
     189                if (preg_match('/^(ht|f)tp:\/\//', $filename)) { 
     190                        return $this->error('Remote files are not supported in this version of getID3() - please copy the file locally first'); 
     191                } 
     192 
     193                $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); 
     194                $filename = preg_replace('#'.preg_quote(DIRECTORY_SEPARATOR).'{2,}#', DIRECTORY_SEPARATOR, $filename); 
     195 
     196                // open local file 
     197                if (file_exists($filename) && ($fp = @fopen($filename, 'rb'))) { 
     198                        // great 
     199                } else { 
     200                        return $this->error('Could not open file "'.$filename.'"'); 
     201                } 
     202 
     203                // set parameters 
     204                $this->info['filesize'] = filesize($filename); 
     205 
     206                // option_max_2gb_check 
     207                if ($this->option_max_2gb_check) { 
     208                        // PHP doesn't support integers larger than 31-bit (~2GB) 
     209                        // filesize() simply returns (filesize % (pow(2, 32)), no matter the actual filesize 
     210                        // ftell() returns 0 if seeking to the end is beyond the range of unsigned integer 
     211                        fseek($fp, 0, SEEK_END); 
     212                        if ((($this->info['filesize'] != 0) && (ftell($fp) == 0)) || 
     213                                ($this->info['filesize'] < 0) || 
     214                                (ftell($fp) < 0)) { 
     215                                        $real_filesize = false; 
     216                                        if (GETID3_OS_ISWINDOWS) { 
     217                                                $commandline = 'dir /-C "'.str_replace('/', DIRECTORY_SEPARATOR, $filename).'"'; 
     218                                                $dir_output = `$commandline`; 
     219                                                if (eregi('1 File\(s\)[ ]+([0-9]+) bytes', $dir_output, $matches)) { 
     220                                                        $real_filesize = (float) $matches[1]; 
     221                                                } 
     222                                        } else { 
     223                                                $commandline = 'ls -o -g -G --time-style=long-iso '.escapeshellarg($filename); 
     224                                                $dir_output = `$commandline`; 
     225                                                if (eregi('([0-9]+) ([0-9]{4}-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}) '.preg_quote($filename).'$', $dir_output, $matches)) { 
     226                                                        $real_filesize = (float) $matches[1]; 
     227                                                } 
     228                                        } 
     229                                        if ($real_filesize === false) { 
     230                                                unset($this->info['filesize']); 
     231                                                fclose($fp); 
     232                                                return $this->error('File is most likely larger than 2GB and is not supported by PHP'); 
     233                                        } elseif ($real_filesize < pow(2, 31)) { 
     234                                                unset($this->info['filesize']); 
     235                                                fclose($fp); 
     236                                                return $this->error('PHP seems to think the file is larger than 2GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org'); 
     237                                        } 
     238                                        $this->info['filesize'] = $real_filesize; 
     239                                        $this->error('File is larger than 2GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.'); 
     240                        } 
     241                } 
     242 
     243                // set more parameters 
     244                $this->info['avdataoffset']        = 0; 
     245                $this->info['avdataend']           = $this->info['filesize']; 
     246                $this->info['fileformat']          = '';                // filled in later 
     247                $this->info['audio']['dataformat'] = '';                // filled in later, unset if not used 
     248                $this->info['video']['dataformat'] = '';                // filled in later, unset if not used 
     249                $this->info['tags']                = array();           // filled in later, unset if not used 
     250                $this->info['error']               = array();           // filled in later, unset if not used 
     251                $this->info['warning']             = array();           // filled in later, unset if not used 
     252                $this->info['comments']            = array();           // filled in later, unset if not used 
     253                $this->info['encoding']            = $this->encoding;   // required by id3v2 and iso modules - can be unset at the end if desired 
     254 
     255                // set redundant parameters - might be needed in some include file 
     256                $this->info['filename']            = basename($filename); 
     257                $this->info['filepath']            = str_replace('\\', '/', realpath(dirname($filename))); 
     258                $this->info['filenamepath']        = $this->info['filepath'].'/'.$this->info['filename']; 
     259 
     260 
     261                // handle ID3v2 tag - done first - already at beginning of file 
     262                // ID3v2 detection (even if not parsing) is always done otherwise fileformat is much harder to detect 
     263                if ($this->option_tag_id3v2) { 
     264 
     265                        $GETID3_ERRORARRAY = &$this->info['warning']; 
     266                        if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, false)) { 
     267                                $tag = new getid3_id3v2($fp, $this->info); 
     268                                unset($tag); 
     269                        } 
     270 
     271                } else { 
     272 
     273                        fseek($fp, 0, SEEK_SET); 
     274                        $header = fread($fp, 10); 
     275                        if (substr($header, 0, 3) == 'ID3'  &&  strlen($header) == 10) { 
     276                                $this->info['id3v2']['header']           = true; 
     277                                $this->info['id3v2']['majorversion']     = ord($header{3}); 
     278                                $this->info['id3v2']['minorversion']     = ord($header{4}); 
     279                                $this->info['id3v2']['headerlength']     = getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length 
     280 
     281                                $this->info['id3v2']['tag_offset_start'] = 0; 
     282                                $this->info['id3v2']['tag_offset_end']   = $this->info['id3v2']['tag_offset_start'] + $this->info['id3v2']['headerlength']; 
     283                                $this->info['avdataoffset']              = $this->info['id3v2']['tag_offset_end']; 
     284                        } 
     285 
     286                } 
     287 
     288 
     289                // handle ID3v1 tag 
     290                if ($this->option_tag_id3v1) { 
     291                        if (!@include_once(GETID3_INCLUDEPATH.'module.tag.id3v1.php')) { 
     292                                return $this->error('module.tag.id3v1.php is missing - you may disable option_tag_id3v1.'); 
     293                        } 
     294                        $tag = new getid3_id3v1($fp, $this->info); 
     295                        unset($tag); 
     296                } 
     297 
     298                // handle APE tag 
     299                if ($this->option_tag_apetag) { 
     300                        if (!@include_once(GETID3_INCLUDEPATH.'module.tag.apetag.php')) { 
     301                                return $this->error('module.tag.apetag.php is missing - you may disable option_tag_apetag.'); 
     302                        } 
     303                        $tag = new getid3_apetag($fp, $this->info); 
     304                        unset($tag); 
     305                } 
     306 
     307                // handle lyrics3 tag 
     308                if ($this->option_tag_lyrics3) { 
     309                        if (!@include_once(GETID3_INCLUDEPATH.'module.tag.lyrics3.php')) { 
     310                                return $this->error('module.tag.lyrics3.php is missing - you may disable option_tag_lyrics3.'); 
     311                        } 
     312                        $tag = new getid3_lyrics3($fp, $this->info); 
     313                        unset($tag); 
     314                } 
     315 
     316                // read 32 kb file data 
     317                fseek($fp, $this->info['avdataoffset'], SEEK_SET); 
     318                $formattest = fread($fp, 32774); 
     319 
     320                // determine format 
     321                $determined_format = $this->GetFileFormat($formattest, $filename); 
     322 
     323                // unable to determine file format 
     324                if (!$determined_format) { 
     325                        fclose($fp); 
     326                        return $this->error('unable to determine file format'); 
     327                } 
     328 
     329                // check for illegal ID3 tags 
     330                if (isset($determined_format['fail_id3']) && (in_array('id3v1', $this->info['tags']) || in_array('id3v2', $this->info['tags']))) { 
     331                        if ($determined_format['fail_id3'] === 'ERROR') { 
     332                                fclose($fp); 
     333                                return $this->error('ID3 tags not allowed on this file type.'); 
     334                        } elseif ($determined_format['fail_id3'] === 'WARNING') { 
     335                                $this->info['warning'][] = 'ID3 tags not allowed on this file type.'; 
     336                        } 
     337                } 
     338 
     339                // check for illegal APE tags 
     340                if (isset($determined_format['fail_ape']) && in_array('ape', $this->info['tags'])) { 
     341                        if ($determined_format['fail_ape'] === 'ERROR') { 
     342                                fclose($fp); 
     343                                return $this->error('APE tags not allowed on this file type.'); 
     344                        } elseif ($determined_format['fail_ape'] === 'WARNING') { 
     345                                $this->info['warning'][] = 'APE tags not allowed on this file type.'; 
     346                        } 
     347                } 
     348 
     349                // set mime type 
     350                $this->info['mime_type'] = $determined_format['mime_type']; 
     351 
     352                // supported format signature pattern detected, but module deleted 
     353                if (!file_exists(GETID3_INCLUDEPATH.$determined_format['include'])) { 
     354                        fclose($fp); 
     355                        return $this->error('Format not supported, module "'.$determined_format['include'].'" was removed.'); 
     356                } 
     357 
     358                // module requires iconv support 
     359        if (!function_exists('iconv') && @$determined_format['iconv_req']) { 
     360                    return $this->error('iconv support is required for this module ('.$determined_format['include'].').'); 
     361                } 
     362 
     363                // include module 
     364                include_once(GETID3_INCLUDEPATH.$determined_format['include']); 
     365 
     366                // instantiate module class 
     367                $class_name = 'getid3_'.$determined_format['module']; 
     368                if (!class_exists($class_name)) { 
     369                        return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.'); 
     370                } 
     371                if (isset($determined_format['option'])) { 
     372                        $class = new $class_name($fp, $this->info, $determined_format['option']); 
     373                } else { 
     374                        $class = new $class_name($fp, $this->info); 
     375                } 
     376                unset($class); 
     377 
     378                // close file 
     379                fclose($fp); 
     380 
     381                // process all tags - copy to 'tags' and convert charsets 
     382                if ($this->option_tags_process) { 
     383                        $this->HandleAllTags(); 
     384                } 
     385 
     386                // perform more calculations 
     387                if ($this->option_extra_info) { 
     388                        $this->ChannelsBitratePlaytimeCalculations(); 
     389                        $this->CalculateCompressionRatioVideo(); 
     390                        $this->CalculateCompressionRatioAudio(); 
     391                        $this->CalculateReplayGain(); 
     392                        $this->ProcessAudioStreams(); 
     393                } 
     394 
     395                // get the MD5 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags 
     396                if ($this->option_md5_data) { 
     397                        // do not cald md5_data if md5_data_source is present - set by flac only - future MPC/SV8 too 
     398                        if (!$this->option_md5_data_source || empty($this->info['md5_data_source'])) { 
     399                                $this->getHashdata('md5'); 
     400                        } 
     401                } 
     402 
     403                // get the SHA1 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags 
     404                if ($this->option_sha1_data) { 
     405                        $this->getHashdata('sha1'); 
     406                } 
     407 
     408                // remove undesired keys 
     409                $this->CleanUp(); 
     410 
     411                // restore magic_quotes_runtime setting 
     412                set_magic_quotes_runtime($old_magic_quotes_runtime); 
     413 
     414                // return info array 
     415                return $this->info; 
     416        } 
     417 
     418 
     419        // private: error handling 
     420        function error($message) { 
     421 
     422                $this->CleanUp(); 
     423 
     424                $this->info['error'][] = $message; 
     425                return $this->info; 
     426        } 
     427 
     428 
     429        // private: warning handling 
     430        function warning($message) { 
     431                $this->info['warning'][] = $message; 
     432                return true; 
     433        } 
     434 
     435 
     436        // private: CleanUp 
     437        function CleanUp() { 
     438 
     439                // remove possible empty keys 
     440                $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate'); 
     441                foreach ($AVpossibleEmptyKeys as $dummy => $key) { 
     442                        if (empty($this->info['audio'][$key]) && isset($this->info['audio'][$key])) { 
     443                                unset($this->info['audio'][$key]); 
     444                        } 
     445                        if (empty($this->info['video'][$key]) && isset($this->info['video'][$key])) { 
     446                                unset($this->info['video'][$key]); 
     447                        } 
     448                } 
     449 
     450                // remove empty root keys 
     451                if (!empty($this->info)) { 
     452                        foreach ($this->info as $key => $value) { 
     453                                if (empty($this->info[$key]) && ($this->info[$key] !== 0) && ($this->info[$key] !== '0')) { 
     454                                        unset($this->info[$key]); 
     455                                } 
     456                        } 
     457                } 
     458 
     459                // remove meaningless entries from unknown-format files 
     460                if (empty($this->info['fileformat'])) { 
     461                        if (isset($this->info['avdataoffset'])) { 
     462                                unset($this->info['avdataoffset']); 
     463                        } 
     464                        if (isset($this->info['avdataend'])) { 
     465                                unset($this->info['avdataend']); 
     466                        } 
     467                } 
     468        } 
     469 
     470 
     471        // return array containing information about all supported formats 
     472        function GetFileFormatArray() { 
     473                static $format_info = array(); 
     474                if (empty($format_info)) { 
     475                        $format_info = array( 
     476 
     477                                // Audio formats 
     478 
     479                                // AC-3   - audio      - Dolby AC-3 / Dolby Digital 
     480                                'ac3'  => array( 
     481                                                        'pattern'   => '^\x0B\x77', 
     482                                                        'group'     => 'audio', 
     483                                                        'module'    => 'ac3', 
     484                                                        'mime_type' => 'audio/ac3', 
     485                                                ), 
     486 
     487                                // AAC  - audio       - Advanced Audio Coding (AAC) - ADIF format 
     488                                'adif' => array( 
     489                                                        'pattern'   => '^ADIF', 
     490                                                        'group'     => 'audio', 
     491                                                        'module'    => 'aac', 
     492                                                        'option'    => 'adif', 
     493                                                        'mime_type' => 'application/octet-stream', 
     494                                                        'fail_ape'  => 'WARNING', 
     495                                                ), 
     496 
     497 
     498                                // AAC  - audio       - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3) 
     499                                'adts' => array( 
     500                                                        'pattern'   => '^\xFF[\xF0-\xF1\xF8-\xF9]', 
     501                                                        'group'     => 'audio', 
     502                                                        'module'    => 'aac', 
     503                                                        'option'    => 'adts', 
     504                                                        'mime_type' => 'application/octet-stream', 
     505                                                        'fail_ape'  => 'WARNING', 
     506                                                ), 
     507 
     508 
     509                                // AU   - audio       - NeXT/Sun AUdio (AU) 
     510                                'au'   => array( 
     511                                                        'pattern'   => '^\.snd', 
     512                                                        'group'     => 'audio', 
     513                                                        'module'    => 'au', 
     514                                                        'mime_type' => 'audio/basic', 
     515                                                ), 
     516 
     517                                // AVR  - audio       - Audio Visual Research 
     518                                'avr'  => array( 
     519                                                        'pattern'   => '^2BIT', 
     520                                                        'group'     => 'audio', 
     521                                                        'module'    => 'avr', 
     522                                                        'mime_type' => 'application/octet-stream', 
     523                                                ), 
     524 
     525                                // BONK - audio       - Bonk v0.9+ 
     526                                'bonk' => array( 
     527                                                        'pattern'   => '^\x00(BONK|INFO|META| ID3)', 
     528                                                        'group'     => 'audio', 
     529                                                        'module'    => 'bonk', 
     530                                                        'mime_type' => 'audio/xmms-bonk', 
     531                                                ), 
     532 
     533                                // DSS  - audio       - Digital Speech Standard 
     534                                'dss'  => array( 
     535                                                        'pattern'   => '^[\x02]dss', 
     536                                                        'group'     => 'audio', 
     537                                                        'module'    => 'dss', 
     538                                                        'mime_type' => 'application/octet-stream', 
     539                                                ), 
     540 
     541                                // DTS  - audio       - Dolby Theatre System 
    595542                                'dts'  => array( 
    596543                                                        'pattern'   => '^\x7F\xFE\x80\x01', 
     
    600547                                                ), 
    601548 
    602                 // FLAC - audio       - Free Lossless Audio Codec 
    603                 'flac' => array ( 
    604                             'pattern'   => '^fLaC', 
    605                             'group'     => 'audio', 
    606                             'module'    => 'xiph', 
    607                             'mime_type' => 'audio/x-flac', 
    608                           ), 
    609  
    610                 // LA   - audio       - Lossless Audio (LA) 
    611                 'la'   => array ( 
    612                             'pattern'   => '^LA0[2-4]', 
    613                             'group'     => 'audio', 
    614                             'module'    => 'la', 
    615                             'mime_type' => 'application/octet-stream', 
    616                           ), 
    617  
    618                 // LPAC - audio       - Lossless Predictive Audio Compression (LPAC) 
    619                 'lpac' => array ( 
    620                             'pattern'   => '^LPAC', 
    621                             'group'     => 'audio', 
    622                             'module'    => 'lpac', 
    623                             'mime_type' => 'application/octet-stream', 
    624                           ), 
    625  
    626                 // MIDI - audio       - MIDI (Musical Instrument Digital Interface) 
    627                 'midi' => array ( 
    628                             'pattern'   => '^MThd', 
    629                             'group'     => 'audio', 
    630                             'module'    => 'midi', 
    631                             'mime_type' => 'audio/midi', 
    632                           ), 
    633  
    634                 // MAC  - audio       - Monkey's Audio Compressor 
    635                 'mac'  => array ( 
    636                             'pattern'   => '^MAC ', 
    637                             'group'     => 'audio', 
    638                             'module'    => 'monkey', 
    639                             'mime_type' => 'application/octet-stream', 
    640                           ), 
    641  
    642                 // MOD  - audio       - MODule (assorted sub-formats) 
    643                 'mod'  => array ( 
    644                             'pattern'   => '^.{1080}(M.K.|[5-9]CHN|[1-3][0-9]CH)', 
    645                             'mime_type' => 'audio/mod', 
    646                           ), 
    647  
    648                 // MOD  - audio       - MODule (Impulse Tracker) 
    649                 'it'   => array ( 
    650                             'pattern'   => '^IMPM', 
    651                             'mime_type' => 'audio/it', 
    652                           ), 
    653  
    654                 // MOD  - audio       - MODule (eXtended Module, various sub-formats) 
    655                 'xm'   => array ( 
    656                             'pattern'   => '^Extended Module', 
    657                             'mime_type' => 'audio/xm', 
    658                           ), 
    659  
    660                 // MOD  - audio       - MODule (ScreamTracker) 
    661                 's3m'  => array ( 
    662                             'pattern'   => '^.{44}SCRM', 
    663                             'mime_type' => 'audio/s3m', 
    664                           ), 
    665  
    666                 // MPC  - audio       - Musepack / MPEGplus SV7+ 
    667                 'mpc'  => array ( 
    668                             'pattern'   => '^(MP\+)', 
    669                             'group'     => 'audio', 
    670                             'module'    => 'mpc', 
    671                             'mime_type' => 'audio/x-musepack', 
    672                           ), 
    673  
    674                 // MPC  - audio       - Musepack / MPEGplus SV4-6 
    675                 'mpc_old' => array ( 
    676                             'pattern'   => '^([\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])', 
    677                             'group'     => 'audio', 
    678                             'module'    => 'mpc_old', 
    679                             'mime_type' => 'application/octet-stream', 
    680                           ), 
    681  
    682  
    683                 // MP3  - audio       - MPEG-audio Layer 3 (very similar to AAC-ADTS) 
    684                 'mp3'  => array ( 
    685                             'pattern'   => '^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]', 
    686                             'group'     => 'audio', 
    687                             'module'    => 'mp3', 
    688                             'mime_type' => 'audio/mpeg', 
    689                           ), 
    690  
    691                 // OFR  - audio       - OptimFROG 
    692                 'ofr'  => array ( 
    693                             'pattern'   => '^(\*RIFF|OFR)', 
    694                             'group'     => 'audio', 
    695                             'module'    => 'optimfrog', 
    696                             'mime_type' => 'application/octet-stream', 
    697                           ), 
    698  
    699                 // RKAU - audio       - RKive AUdio compressor 
    700                 'rkau' => array ( 
    701                             'pattern'   => '^RKA', 
    702                             'group'     => 'audio', 
    703                             'module'    => 'rkau', 
    704                             'mime_type' => 'application/octet-stream', 
    705                           ), 
    706  
    707                 // SHN  - audio       - Shorten 
    708                 'shn'  => array ( 
    709                             'pattern'   => '^ajkg', 
    710                             'group'     => 'audio', 
    711                             'module'    => 'shorten', 
    712                             'mime_type' => 'audio/xmms-shn', 
    713                             'fail_id3'  => 'ERROR', 
    714                             'fail_ape'  => 'ERROR', 
    715                           ), 
    716  
    717                 // TTA  - audio       - TTA Lossless Audio Compressor (http://tta.corecodec.org) 
    718                 'tta'  => array ( 
    719                             'pattern'   => '^TTA',  // could also be '^TTA(\x01|\x02|\x03|2|1)' 
    720                             'group'     => 'audio', 
    721                             'module'    => 'tta', 
    722                             'mime_type' => 'application/octet-stream', 
    723                           ), 
    724  
    725                 // VOC  - audio       - Creative Voice (VOC) 
    726                 'voc'  => array ( 
    727                             'pattern'   => '^Creative Voice File', 
    728                             'group'     => 'audio', 
    729                             'module'    => 'voc', 
    730                             'mime_type' => 'audio/voc', 
    731                           ), 
    732  
    733                 // VQF  - audio       - transform-domain weighted interleave Vector Quantization Format (VQF) 
    734                 'vqf'  => array ( 
    735                             'pattern'   => '^TWIN', 
    736                             'group'     => 'audio', 
    737                             'module'    => 'vqf', 
    738                             'mime_type' => 'application/octet-stream', 
    739                           ), 
    740  
    741                 // WV  - audio        - WavPack (v4.0+) 
    742                 'vw'  => array( 
    743                             'pattern'   => '^wvpk', 
    744                             'group'     => 'audio', 
    745                             'module'    => 'wavpack', 
    746                             'mime_type' => 'application/octet-stream', 
    747                           ), 
    748  
    749  
    750                 // Audio-Video formats 
    751  
    752                 // ASF  - audio/video - Advanced Streaming Format, Windows Media Video, Windows Media Audio 
    753                 'asf'  => array ( 
    754                             'pattern'   => '^\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C', 
    755                             'group'     => 'audio-video', 
    756                             'module'    => 'asf', 
    757                             'mime_type' => 'video/x-ms-asf', 
    758                           ), 
    759  
    760                 // BINK  - audio/video - Bink / Smacker 
    761                 'bink' => array( 
    762                             'pattern'   => '^(BIK|SMK)', 
    763                             'mime_type' => 'application/octet-stream', 
    764                           ), 
    765  
    766                 // FLV  - audio/video - FLash Video 
    767                 'flv' => array( 
    768                             'pattern'   => '^FLV\x01', 
    769                             'group'     => 'audio-video', 
    770                             'module'    => 'flv', 
    771                             'mime_type' => 'video/x-flv', 
    772                           ), 
    773  
    774                 // MKAV - audio/video - Mastroka 
    775                 'matroska' => array ( 
    776                             'pattern'   => '^\x1A\x45\xDF\xA3', 
    777                             'mime_type' => 'application/octet-stream', 
    778                           ), 
    779  
    780                 // MPEG - audio/video - MPEG (Moving Pictures Experts Group) 
    781                 'mpeg' => array ( 
    782                             'pattern'   => '^\x00\x00\x01(\xBA|\xB3)', 
    783                             'group'     => 'audio-video', 
    784                             'module'    => 'mpeg', 
    785                             'mime_type' => 'video/mpeg', 
    786                           ), 
    787  
    788                 // NSV  - audio/video - Nullsoft Streaming Video (NSV) 
    789                 'nsv'  => array ( 
    790                             'pattern'   => '^NSV[sf]', 
    791                             'group'     => 'audio-video', 
    792                             'module'    => 'nsv', 
    793                             'mime_type' => 'application/octet-stream', 
    794                           ), 
    795  
    796                 // Ogg  - audio/video - Ogg (Ogg Vorbis, OggFLAC, Speex, Ogg Theora(*), Ogg Tarkin(*)) 
    797                 'ogg'  => array ( 
    798                             'pattern'   => '^OggS', 
    799                             'group'     => 'audio', 
    800                             'module'    => 'xiph', 
    801                             'mime_type' => 'application/ogg', 
    802                             'fail_id3'  => 'WARNING', 
    803                             'fail_ape'  => 'WARNING', 
    804                           ), 
    805  
    806                 // QT   - audio/video - Quicktime 
    807                 'quicktime' => array ( 
    808                             'pattern'   => '^.{4}(cmov|free|ftyp|mdat|moov|pnot|skip|wide)', 
    809                             'group'     => 'audio-video', 
    810                             'module'    => 'quicktime', 
    811                             'mime_type' => 'video/quicktime', 
    812                           ), 
    813  
    814                 // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF) 
    815                 'riff' => array ( 
    816                             'pattern'   => '^(RIFF|SDSS|FORM)', 
    817                             'group'     => 'audio-video', 
    818                             'module'    => 'riff', 
    819                             'mime_type' => 'audio/x-wave', 
    820                             'fail_ape'  => 'WARNING', 
    821                           ), 
    822  
    823                 // Real - audio/video - RealAudio, RealVideo 
    824                 'real' => array ( 
    825                             'pattern'   => '^(\.RMF|.ra)', 
    826                             'group'     => 'audio-video', 
    827                             'module'    => 'real', 
    828                             'mime_type' => 'audio/x-realaudio', 
    829                           ), 
    830  
    831                 // SWF - audio/video - ShockWave Flash 
    832                 'swf' => array ( 
    833                             'pattern'   => '^(F|C)WS', 
    834                             'group'     => 'audio-video', 
    835                             'module'    => 'swf', 
    836                             'mime_type' => 'application/x-shockwave-flash', 
    837                           ), 
    838  
    839  
    840                 // Still-Image formats 
    841  
    842                 // BMP  - still image - Bitmap (Windows, OS/2; uncompressed, RLE8, RLE4) 
    843                 'bmp'  => array ( 
    844                             'pattern'   => '^BM', 
    845                             'group'     => 'graphic', 
    846                             'module'    => 'bmp', 
    847                             'mime_type' => 'image/bmp', 
    848                             'fail_id3'  => 'ERROR', 
    849                             'fail_ape'  => 'ERROR', 
    850                           ), 
    851  
    852                 // GIF  - still image - Graphics Interchange Format 
    853                 'gif'  => array ( 
    854                             'pattern'   => '^GIF', 
    855                             'group'     => 'graphic', 
    856                             'module'    => 'gif', 
    857                             'mime_type' => 'image/gif', 
    858                             'fail_id3'  => 'ERROR', 
    859                             'fail_ape'  => 'ERROR', 
    860                           ), 
    861  
    862                 // JPEG - still image - Joint Photographic Experts Group (JPEG) 
    863                 'jpeg'  => array ( 
    864                             'pattern'   => '^\xFF\xD8\xFF', 
    865                             'group'     => 'graphic', 
    866                             'module'    => 'jpeg', 
    867                             'mime_type' => 'image/jpeg', 
    868                             'fail_id3'  => 'ERROR', 
    869                             'fail_ape'  => 'ERROR', 
    870                           ), 
    871  
    872                 // PCD  - still image - Kodak Photo CD 
    873                 'pcd'  => array ( 
    874                             'pattern'   => '^.{2048}PCD_IPI\x00', 
    875                             'group'     => 'graphic', 
    876                             'module'    => 'pcd', 
    877                             'mime_type' => 'image/x-photo-cd', 
    878                             'fail_id3'  => 'ERROR', 
    879                             'fail_ape'  => 'ERROR', 
    880                           ), 
    881  
    882  
    883                 // PNG  - still image - Portable Network Graphics (PNG) 
    884                 'png'  => array ( 
    885                             'pattern'   => '^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A', 
    886                             'group'     => 'graphic', 
    887                             'module'    => 'png', 
    888                             'mime_type' => 'image/png', 
    889                             'fail_id3'  => 'ERROR', 
    890                             'fail_ape'  => 'ERROR', 
    891                           ), 
     549                                // FLAC - audio       - Free Lossless Audio Codec 
     550                                'flac' => array( 
     551                                                        'pattern'   => '^fLaC', 
     552                                                        'group'     => 'audio', 
     553                                                        'module'    => 'flac', 
     554                                                        'mime_type' => 'audio/x-flac', 
     555                                                ), 
     556 
     557                                // LA   - audio       - Lossless Audio (LA) 
     558                                'la'   => array( 
     559                                                        'pattern'   => '^LA0[2-4]', 
     560                                                        'group'     => 'audio', 
     561                                                        'module'    => 'la', 
     562                                                        'mime_type' => 'application/octet-stream', 
     563                                                ), 
     564 
     565                                // LPAC - audio       - Lossless Predictive Audio Compression (LPAC) 
     566                                'lpac' => array( 
     567                                                        'pattern'   => '^LPAC', 
     568                                                        'group'     => 'audio', 
     569                                                        'module'    => 'lpac', 
     570                                                        'mime_type' => 'application/octet-stream', 
     571                                                ), 
     572 
     573                                // MIDI - audio       - MIDI (Musical Instrument Digital Interface) 
     574                                'midi' => array( 
     575                                                        'pattern'   => '^MThd', 
     576                                                        'group'     => 'audio', 
     577                                                        'module'    => 'midi', 
     578                                                        'mime_type' => 'audio/midi', 
     579                                                ), 
     580 
     581                                // MAC  - audio       - Monkey's Audio Compressor 
     582                                'mac'  => array( 
     583                                                        'pattern'   => '^MAC ', 
     584                                                        'group'     => 'audio', 
     585                                                        'module'    => 'monkey', 
     586                                                        'mime_type' => 'application/octet-stream', 
     587                                                ), 
     588 
     589// has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available 
     590//                              // MOD  - audio       - MODule (assorted sub-formats) 
     591//                              'mod'  => array( 
     592//                                                      'pattern'   => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)', 
     593//                                                      'group'     => 'audio', 
     594//                                                      'module'    => 'mod', 
     595//                                                      'option'    => 'mod', 
     596//                                                      'mime_type' => 'audio/mod', 
     597//                                              ), 
     598 
     599                                // MOD  - audio       - MODule (Impulse Tracker) 
     600                                'it'   => array( 
     601                                                        'pattern'   => '^IMPM', 
     602                                                        'group'     => 'audio', 
     603                                                        'module'    => 'mod', 
     604                                                        'option'    => 'it', 
     605                                                        'mime_type' => 'audio/it', 
     606                                                ), 
     607 
     608                                // MOD  - audio       - MODule (eXtended Module, various sub-formats) 
     609                                'xm'   => array( 
     610                                                        'pattern'   => '^Extended Module', 
     611                                                        'group'     => 'audio', 
     612                                                        'module'    => 'mod', 
     613                                                        'option'    => 'xm', 
     614                                                        'mime_type' => 'audio/xm', 
     615                                                ), 
     616 
     617                                // MOD  - audio       - MODule (ScreamTracker) 
     618                                's3m'  => array( 
     619                                                        'pattern'   => '^.{44}SCRM', 
     620                                                        'group'     => 'audio', 
     621                                                        'module'    => 'mod', 
     622                                                        'option'    => 's3m', 
     623                                                        'mime_type' => 'audio/s3m', 
     624                                                ), 
     625 
     626                                // MPC  - audio       - Musepack / MPEGplus 
     627                                'mpc'  => array( 
     628                                                        'pattern'   => '^(MPCK|MP\+|[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])', 
     629                                                        'group'     => 'audio', 
     630                                                        'module'    => 'mpc', 
     631                                                        'mime_type' => 'audio/x-musepack', 
     632                                                ), 
     633 
     634                                // MP3  - audio       - MPEG-audio Layer 3 (very similar to AAC-ADTS) 
     635                                'mp3'  => array( 
     636                                                        'pattern'   => '^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]', 
     637                                                        'group'     => 'audio', 
     638                                                        'module'    => 'mp3', 
     639                                                        'mime_type' => 'audio/mpeg', 
     640                                                ), 
     641 
     642                                // OFR  - audio       - OptimFROG 
     643                                'ofr'  => array( 
     644                                                        'pattern'   => '^(\*RIFF|OFR)', 
     645                                                        'group'     => 'audio', 
     646                                                        'module'    => 'optimfrog', 
     647                                                        'mime_type' => 'application/octet-stream', 
     648                                                ), 
     649 
     650                                // RKAU - audio       - RKive AUdio compressor 
     651                                'rkau' => array( 
     652                                                        'pattern'   => '^RKA', 
     653                                                        'group'     => 'audio', 
     654                                                        'module'    => 'rkau', 
     655                                                        'mime_type' => 'application/octet-stream', 
     656                                                ), 
     657 
     658                                // SHN  - audio       - Shorten 
     659                                'shn'  => array( 
     660                                                        'pattern'   => '^ajkg', 
     661                                                        'group'     => 'audio', 
     662                                                        'module'    => 'shorten', 
     663                                                        'mime_type' => 'audio/xmms-shn', 
     664                                                        'fail_id3'  => 'ERROR', 
     665                                                        'fail_ape'  => 'ERROR', 
     666                                                ), 
     667 
     668                                // TTA  - audio       - TTA Lossless Audio Compressor (http://tta.corecodec.org) 
     669                                'tta'  => array( 
     670                                                        'pattern'   => '^TTA',  // could also be '^TTA(\x01|\x02|\x03|2|1)' 
     671                                                        'group'     => 'audio', 
     672                                                        'module'    => 'tta', 
     673                                                        'mime_type' => 'application/octet-stream', 
     674                                                ), 
     675 
     676                                // VOC  - audio       - Creative Voice (VOC) 
     677                                'voc'  => array( 
     678                                                        'pattern'   => '^Creative Voice File', 
     679                                                        'group'     => 'audio', 
     680                                                        'module'    => 'voc', 
     681                                                        'mime_type' => 'audio/voc', 
     682                                                ), 
     683 
     684                                // VQF  - audio       - transform-domain weighted interleave Vector Quantization Format (VQF) 
     685                                'vqf'  => array( 
     686                                                        'pattern'   => '^TWIN', 
     687                                                        'group'     => 'audio', 
     688                                                        'module'    => 'vqf', 
     689                                                        'mime_type' => 'application/octet-stream', 
     690                                                ), 
     691 
     692                                // WV  - audio        - WavPack (v4.0+) 
     693                                'wv'   => array( 
     694                                                        'pattern'   => '^wvpk', 
     695                                                        'group'     => 'audio', 
     696                                                        'module'    => 'wavpack', 
     697                                                        'mime_type' => 'application/octet-stream', 
     698                                                ), 
     699 
     700 
     701                                // Audio-Video formats 
     702 
     703                                // ASF  - audio/video - Advanced Streaming Format, Windows Media Video, Windows Media Audio 
     704                                'asf'  => array( 
     705                                                        'pattern'   => '^\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C', 
     706                                                        'group'     => 'audio-video', 
     707                                                        'module'    => 'asf', 
     708                                                        'mime_type' => 'video/x-ms-asf', 
     709                                                        'iconv_req' => false, 
     710                                                ), 
     711 
     712                                // BINK - audio/video - Bink / Smacker 
     713                                'bink' => array( 
     714                                                        'pattern'   => '^(BIK|SMK)', 
     715                                                        'group'     => 'audio-video', 
     716                                                        'module'    => 'bink', 
     717                                                        'mime_type' => 'application/octet-stream', 
     718                                                ), 
     719 
     720                                // FLV  - audio/video - FLash Video 
     721                                'flv' => array( 
     722                                                        'pattern'   => '^FLV\x01', 
     723                                                        'group'     => 'audio-video', 
     724                                                        'module'    => 'flv', 
     725                                                        'mime_type' => 'video/x-flv', 
     726                                                ), 
     727 
     728                                // MKAV - audio/video - Mastroka 
     729                                'matroska' => array( 
     730                                                        'pattern'   => '^\x1A\x45\xDF\xA3', 
     731                                                        'group'     => 'audio-video', 
     732                                                        'module'    => 'matroska', 
     733                                                        'mime_type' => 'video/x-matroska', // may also be audio/x-matroska 
     734                                                ), 
     735 
     736                                // MPEG - audio/video - MPEG (Moving Pictures Experts Group) 
     737                                'mpeg' => array( 
     738                                                        'pattern'   => '^\x00\x00\x01(\xBA|\xB3)', 
     739                                                        'group'     => 'audio-video', 
     740                                                        'module'    => 'mpeg', 
     741                                                        'mime_type' => 'video/mpeg', 
     742                                                ), 
     743 
     744                                // NSV  - audio/video - Nullsoft Streaming Video (NSV) 
     745                                'nsv'  => array( 
     746                                                        'pattern'   => '^NSV[sf]', 
     747                                                        'group'     => 'audio-video', 
     748                                                        'module'    => 'nsv', 
     749                                                        'mime_type' => 'application/octet-stream', 
     750                                                ), 
     751 
     752                                // Ogg  - audio/video - Ogg (Ogg-Vorbis, Ogg-FLAC, Speex, Ogg-Theora(*), Ogg-Tarkin(*)) 
     753                                'ogg'  => array( 
     754                                                        'pattern'   => '^OggS', 
     755                                                        'group'     => 'audio', 
     756                                                        'module'    => 'ogg', 
     757                                                        'mime_type' => 'application/ogg', 
     758                                                        'fail_id3'  => 'WARNING', 
     759                                                        'fail_ape'  => 'WARNING', 
     760                                                ), 
     761 
     762                                // QT   - audio/video - Quicktime 
     763                                'quicktime' => array( 
     764                                                        'pattern'   => '^.{4}(cmov|free|ftyp|mdat|moov|pnot|skip|wide)', 
     765                                                        'group'     => 'audio-video', 
     766                                                        'module'    => 'quicktime', 
     767                                                        'mime_type' => 'video/quicktime', 
     768                                                ), 
     769 
     770                                // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF) 
     771                                'riff' => array( 
     772                                                        'pattern'   => '^(RIFF|SDSS|FORM)', 
     773                                                        'group'     => 'audio-video', 
     774                                                        'module'    => 'riff', 
     775                                                        'mime_type' => 'audio/x-wave', 
     776                                                        'fail_ape'  => 'WARNING', 
     777                                                ), 
     778 
     779                                // Real - audio/video - RealAudio, RealVideo 
     780                                'real' => array( 
     781                                                        'pattern'   => '^(\\.RMF|\\.ra)', 
     782                                                        'group'     => 'audio-video', 
     783                                                        'module'    => 'real', 
     784                                                        'mime_type' => 'audio/x-realaudio', 
     785                                                ), 
     786 
     787                                // SWF - audio/video - ShockWave Flash 
     788                                'swf' => array( 
     789                                                        'pattern'   => '^(F|C)WS', 
     790                                                        'group'     => 'audio-video', 
     791                                                        'module'    => 'swf', 
     792                                                        'mime_type' => 'application/x-shockwave-flash', 
     793                                                ), 
     794 
     795 
     796                                // Still-Image formats 
     797 
     798                                // BMP  - still image - Bitmap (Windows, OS/2; uncompressed, RLE8, RLE4) 
     799                                'bmp'  => array( 
     800                                                        'pattern'   => '^BM', 
     801                                                        'group'     => 'graphic', 
     802                                                        'module'    => 'bmp', 
     803                                                        'mime_type' => 'image/bmp', 
     804                                                        'fail_id3'  => 'ERROR', 
     805                                                        'fail_ape'  => 'ERROR', 
     806                                                ), 
     807 
     808                                // GIF  - still image - Graphics Interchange Format 
     809                                'gif'  => array( 
     810                                                        'pattern'   => '^GIF', 
     811                                                        'group'     => 'graphic', 
     812                                                        'module'    => 'gif', 
     813                                                        'mime_type' => 'image/gif', 
     814                                                        'fail_id3'  => 'ERROR', 
     815                                                        'fail_ape'  => 'ERROR', 
     816                                                ), 
     817 
     818                                // JPEG - still image - Joint Photographic Experts Group (JPEG) 
     819                                'jpg'  => array( 
     820                                                        'pattern'   => '^\xFF\xD8\xFF', 
     821                                                        'group'     => 'graphic', 
     822                                                        'module'    => 'jpg', 
     823                                                        'mime_type' => 'image/jpeg', 
     824                                                        'fail_id3'  => 'ERROR', 
     825                                                        'fail_ape'  => 'ERROR', 
     826                                                ), 
     827 
     828                                // PCD  - still image - Kodak Photo CD 
     829                                'pcd'  => array( 
     830                                                        'pattern'   => '^.{2048}PCD_IPI\x00', 
     831                                                        'group'     => 'graphic', 
     832                                                        'module'    => 'pcd', 
     833                                                        'mime_type' => 'image/x-photo-cd', 
     834                                                        'fail_id3'  => 'ERROR', 
     835                                                        'fail_ape'  => 'ERROR', 
     836                                                ), 
     837 
     838 
     839                                // PNG  - still image - Portable Network Graphics (PNG) 
     840                                'png'  => array( 
     841                                                        'pattern'   => '^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A', 
     842                                                        'group'     => 'graphic', 
     843                                                        'module'    => 'png', 
     844                                                        'mime_type' => 'image/png', 
     845                                                        'fail_id3'  => 'ERROR', 
     846                                                        'fail_ape'  => 'ERROR', 
     847                                                ), 
    892848 
    893849 
     
    895851                                'svg'  => array( 
    896852                                                        'pattern'   => '<!DOCTYPE svg PUBLIC ', 
     853                                                        'group'     => 'graphic', 
     854                                                        'module'    => 'svg', 
    897855                                                        'mime_type' => 'image/svg+xml', 
    898856                                                        'fail_id3'  => 'ERROR', 
     
    901859 
    902860 
    903                 // TIFF  - still image - Tagged Information File Format (TIFF) 
    904                 'tiff' => array ( 
    905                             'pattern'   => '^(II\x2A\x00|MM\x00\x2A)', 
    906                             'group'     => 'graphic', 
    907                             'module'    => 'tiff', 
    908                             'mime_type' => 'image/tiff', 
    909                             'fail_id3'  => 'ERROR', 
    910                             'fail_ape'  => 'ERROR', 
    911                           ), 
    912  
    913  
    914                 // Data formats 
    915  
    916                 'exe'  => array( 
    917                             'pattern'   => '^MZ', 
    918                             'mime_type' => 'application/octet-stream', 
    919                             'fail_id3'  => 'ERROR', 
    920                             'fail_ape'  => 'ERROR', 
    921                           ), 
    922  
    923                 // ISO  - data        - International Standards Organization (ISO) CD-ROM Image 
    924                 'iso'  => array ( 
    925                             'pattern'   => '^.{32769}CD001', 
    926                             'group'     => 'misc', 
    927                             'module'    => 'iso', 
    928                             'mime_type' => 'application/octet-stream', 
    929                             'fail_id3'  => 'ERROR', 
    930                             'fail_ape'  => 'ERROR', 
    931                           ), 
    932  
    933                 // RAR  - data        - RAR compressed data 
    934                 'rar'  => array( 
    935                             'pattern'   => '^Rar\!', 
    936                             'mime_type' => 'application/octet-stream', 
    937                             'fail_id3'  => 'ERROR', 
    938                             'fail_ape'  => 'ERROR', 
    939                           ), 
    940  
    941                 // SZIP - audio       - SZIP compressed data 
    942                 'szip' => array ( 
    943                             'pattern'   => '^SZ\x0A\x04', 
    944                             'group'     => 'archive', 
    945                             'module'    => 'szip', 
    946                             'mime_type' => 'application/octet-stream', 
    947                             'fail_id3'  => 'ERROR', 
    948                             'fail_ape'  => 'ERROR', 
    949                           ), 
    950  
    951                 // TAR  - data        - TAR compressed data 
    952                 'tar'  => array( 
    953                             'pattern'   => '^.{100}[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20\x00]{12}[0-9\x20\x00]{12}', 
    954                             'group'     => 'archive', 
    955                             'module'    => 'tar', 
    956                             'mime_type' => 'application/x-tar', 
    957                             'fail_id3'  => 'ERROR', 
    958                             'fail_ape'  => 'ERROR', 
    959                           ), 
    960  
    961                 // GZIP  - data        - GZIP compressed data 
    962                 'gz'  => array( 
    963                             'pattern'   => '^\x1F\x8B\x08', 
    964                             'group'     => 'archive', 
    965                             'module'    => 'gzip', 
    966                             'mime_type' => 'application/x-gzip', 
    967                             'fail_id3'  => 'ERROR', 
    968                             'fail_ape'  => 'ERROR', 
    969                           ), 
    970  
    971  
    972                 // ZIP  - data        - ZIP compressed data 
    973                 'zip'  => array ( 
    974                             'pattern'   => '^PK\x03\x04', 
    975                             'group'     => 'archive', 
    976                             'module'    => 'zip', 
    977                             'mime_type' => 'application/zip', 
    978                             'fail_id3'  => 'ERROR', 
    979                             'fail_ape'  => 'ERROR', 
    980                           ), 
    981  
     861                                // TIFF  - still image - Tagged Information File Format (TIFF) 
     862                                'tiff' => array( 
     863                                                        'pattern'   => '^(II\x2A\x00|MM\x00\x2A)', 
     864                                                        'group'     => 'graphic', 
     865                                                        'module'    => 'tiff', 
     866                                                        'mime_type' => 'image/tiff', 
     867                                                        'fail_id3'  => 'ERROR', 
     868                                                        'fail_ape'  => 'ERROR', 
     869                                                ), 
     870 
     871 
     872                                // Data formats 
     873 
     874                                // ISO  - data        - International Standards Organization (ISO) CD-ROM Image 
     875                                'iso'  => array( 
     876                                                        'pattern'   => '^.{32769}CD001', 
     877                                                        'group'     => 'misc', 
     878                                                        'module'    => 'iso', 
     879                                                        'mime_type' => 'application/octet-stream', 
     880                                                        'fail_id3'  => 'ERROR', 
     881                                                        'fail_ape'  => 'ERROR', 
     882                                                        'iconv_req' => false, 
     883                                                ), 
     884 
     885                                // RAR  - data        - RAR compressed data 
     886                                'rar'  => array( 
     887                                                        'pattern'   => '^Rar\!', 
     888                                                        'group'     => 'archive', 
     889                                                        'module'    => 'rar', 
     890                                                        'mime_type' => 'application/octet-stream', 
     891                                                        'fail_id3'  => 'ERROR', 
     892                                                        'fail_ape'  => 'ERROR', 
     893                                                ), 
     894 
     895                                // SZIP - audio/data  - SZIP compressed data 
     896                                'szip' => array( 
     897                                                        'pattern'   => '^SZ\x0A\x04', 
     898                                                        'group'     => 'archive', 
     899                                                        'module'    => 'szip', 
     900                                                        'mime_type' => 'application/octet-stream', 
     901                                                        'fail_id3'  => 'ERROR', 
     902                                                        'fail_ape'  => 'ERROR', 
     903                                                ), 
     904 
     905                                // TAR  - data        - TAR compressed data 
     906                                'tar'  => array( 
     907                                                        'pattern'   => '^.{100}[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20\x00]{12}[0-9\x20\x00]{12}', 
     908                                                        'group'     => 'archive', 
     909                                                        'module'    => 'tar', 
     910                                                        'mime_type' => 'application/x-tar', 
     911                                                        'fail_id3'  => 'ERROR', 
     912                                                        'fail_ape'  => 'ERROR', 
     913                                                ), 
     914 
     915                                // GZIP  - data        - GZIP compressed data 
     916                                'gz'  => array( 
     917                                                        'pattern'   => '^\x1F\x8B\x08', 
     918                                                        'group'     => 'archive', 
     919                                                        'module'    => 'gzip', 
     920                                                        'mime_type' => 'application/x-gzip', 
     921                                                        'fail_id3'  => 'ERROR', 
     922                                                        'fail_ape'  => 'ERROR', 
     923                                                ), 
     924 
     925                                // ZIP  - data         - ZIP compressed data 
     926                                'zip'  => array( 
     927                                                        'pattern'   => '^PK\x03\x04', 
     928                                                        'group'     => 'archive', 
     929                                                        'module'    => 'zip', 
     930                                                        'mime_type' => 'application/zip', 
     931                                                        'fail_id3'  => 'ERROR', 
     932                                                        'fail_ape'  => 'ERROR', 
     933                                                ), 
     934 
     935 
     936                                // Misc other formats 
    982937 
    983938                // PAR2 - data        - Parity Volume Set Specification 2.0 
    984939                'par2' => array ( 
    985940                                        'pattern'   => '^PAR2\x00PKT', 
    986                                                         'mime_type' => 'application/octet-stream', 
    987                                                         'fail_id3'  => 'ERROR', 
    988                                                         'fail_ape'  => 'ERROR', 
    989                                                 ), 
    990  
    991  
    992                  // PDF  - data       - Portable Document Format 
    993                  'pdf' => array( 
    994                             'pattern'   => '^\x25PDF', 
    995                             'mime_type' => 'application/pdf', 
    996                             'fail_id3'  => 'ERROR', 
    997                             'fail_ape'  => 'ERROR', 
    998                            ), 
    999  
    1000                  // DOC  - data       - Microsoft Word 
    1001                  'msoffice' => array( 
    1002                             'pattern'   => '^\xD0\xCF\x11\xE0', // D0CF11E == DOCFILE == Microsoft Office Document 
    1003                             'mime_type' => 'application/octet-stream', 
    1004                             'fail_id3'  => 'ERROR', 
    1005                             'fail_ape'  => 'ERROR', 
    1006                           ), 
    1007             ); 
    1008  
    1009         return $format_info; 
    1010     } 
    1011  
    1012  
    1013  
    1014     // Recursive over array - converts array to $encoding charset from $this->encoding 
    1015     function CharConvert(&$array, $encoding) { 
    1016  
    1017         // Identical encoding - end here 
    1018         if ($encoding == $this->encoding) { 
    1019             return; 
    1020         } 
    1021  
    1022         // Loop thru array 
    1023         foreach ($array as $key => $value) { 
    1024  
    1025             // Go recursive 
    1026             if (is_array($value)) { 
    1027                 $this->CharConvert($array[$key], $encoding); 
    1028             } 
    1029  
    1030             // Convert string 
    1031             elseif (is_string($value)) { 
    1032                 $array[$key] = $this->iconv($encoding, $this->encoding, $value); 
    1033             } 
    1034         } 
    1035     } 
    1036  
    1037  
    1038  
    1039     // Convert and copy tags 
    1040     protected function HandleAllTags() { 
    1041  
    1042         // Key name => array (tag name, character encoding) 
    1043         static $tags = array ( 
    1044             'asf'       => array ('asf',           'UTF-16LE'), 
    1045             'midi'      => array ('midi',          'ISO-8859-1'), 
    1046             'nsv'       => array ('nsv',           'ISO-8859-1'), 
    1047             'ogg'       => array ('vorbiscomment', 'UTF-8'), 
    1048             'png'       => array ('png',           'UTF-8'), 
    1049             'tiff'      => array ('tiff',          'ISO-8859-1'), 
    1050             'quicktime' => array ('quicktime',     'ISO-8859-1'), 
    1051             'real'      => array ('real',          'ISO-8859-1'), 
    1052             'vqf'       => array ('vqf',           'ISO-8859-1'), 
    1053             'zip'       => array ('zip',           'ISO-8859-1'), 
    1054             'riff'      => array ('riff',          'ISO-8859-1'), 
    1055             'lyrics3'   => array ('lyrics3',       'ISO-8859-1'), 
    1056             'id3v1'     => array ('id3v1',         ''),            // change below - cannot assign variable to static array 
    1057             'id3v2'     => array ('id3v2',         'UTF-8'),       // module converts all frames to UTF-8 
    1058             'ape'       => array ('ape',           'UTF-8') 
    1059         ); 
    1060         $tags['id3v1'][1] = $this->encoding_id3v1; 
    1061  
    1062         // Loop thru tags array 
    1063         foreach ($tags as $comment_name => $tag_name_encoding_array) { 
    1064             list($tag_name, $encoding) = $tag_name_encoding_array; 
    1065  
    1066             // Fill in default encoding type if not already present 
    1067             @$this->info[$comment_name]  and  $this->info[$comment_name]['encoding'] = $encoding; 
    1068  
    1069             // Copy comments if key name set 
    1070             if (@$this->info[$comment_name]['comments']) { 
    1071  
    1072                 foreach ($this->info[$comment_name]['comments'] as $tag_key => $value_array) { 
    1073                     foreach ($value_array as $key => $value) { 
    1074                         if (strlen(trim($value)) > 0) { 
    1075                             $this->info['tags'][$tag_name][trim($tag_key)][] = $value; // do not trim!! Unicode characters will get mangled if trailing nulls are removed! 
    1076                         } 
    1077                     } 
    1078  
    1079                 } 
    1080  
    1081                 if (!@$this->info['tags'][$tag_name]) { 
    1082                     // comments are set but contain nothing but empty strings, so skip 
    1083                     continue; 
    1084                 } 
    1085  
    1086                 $this->CharConvert($this->info['tags'][$tag_name], $encoding); 
    1087             } 
    1088         } 
    1089  
    1090  
    1091         // Merge comments from ['tags'] into common ['comments'] 
    1092         if (@$this->info['tags']) { 
    1093  
    1094             foreach ($this->info['tags'] as $tag_type => $tag_array) { 
    1095  
    1096                 foreach ($tag_array as $tag_name => $tagdata) { 
    1097  
    1098                     foreach ($tagdata as $key => $value) { 
    1099  
    1100                         if (!empty($value)) { 
    1101  
    1102                             if (empty($this->info['comments'][$tag_name])) { 
    1103  
    1104                                 // fall through and append value 
    1105                             } 
    1106                             elseif ($tag_type == 'id3v1') { 
    1107  
    1108                                 $new_value_length = strlen(trim($value)); 
    1109                                 foreach ($this->info['comments'][$tag_name] as $existing_key => $existing_value) { 
    1110                                     $old_value_length = strlen(trim($existing_value)); 
    1111                                     if (($new_value_length <= $old_value_length) && (substr($existing_value, 0, $new_value_length) == trim($value))) { 
    1112                                         // new value is identical but shorter-than (or equal-length to) one already in comments - skip 
    1113                                         break 2; 
    1114                                     } 
    1115                                 } 
    1116                             } 
    1117                             else { 
    1118  
    1119                                 $new_value_length = strlen(trim($value)); 
    1120                                 foreach ($this->info['comments'][$tag_name] as $existing_key => $existing_value) { 
    1121                                     $old_value_length = strlen(trim($existing_value)); 
    1122                                     if (($new_value_length > $old_value_length) && (substr(trim($value), 0, strlen($existing_value)) == $existing_value)) { 
    1123                                         $this->info['comments'][$tag_name][$existing_key] = trim($value); 
    1124                                         break 2; 
    1125                                     } 
    1126                                 } 
    1127                             } 
    1128  
    1129                             if (empty($this->info['comments'][$tag_name]) || !in_array(trim($value), $this->info['comments'][$tag_name])) { 
    1130                                 $this->info['comments'][$tag_name][] = trim($value); 
    1131                             } 
    1132                         } 
    1133                     } 
    1134                 } 
    1135             } 
    1136         } 
    1137  
    1138         return true; 
    1139     } 
     941                                        'group'     => 'misc', 
     942                                                        'module'    => 'par2', 
     943                                                        'mime_type' => 'application/octet-stream', 
     944                                                        'fail_id3'  => 'ERROR', 
     945                                                        'fail_ape'  => 'ERROR', 
     946                                                ), 
     947 
     948                                // PDF  - data        - Portable Document Format 
     949                                'pdf'  => array( 
     950                                                        'pattern'   => '^\x25PDF', 
     951                                                        'group'     => 'misc', 
     952                                                        'module'    => 'pdf', 
     953                                                        'mime_type' => 'application/pdf', 
     954                                                        'fail_id3'  => 'ERROR', 
     955                                                        'fail_ape'  => 'ERROR', 
     956                                                ), 
     957 
     958                                // MSOFFICE  - data   - ZIP compressed data 
     959                                'msoffice' => array( 
     960                                                        'pattern'   => '^\xD0\xCF\x11\xE0', // D0CF11E == DOCFILE == Microsoft Office Document 
     961                                                        'group'     => 'misc', 
     962                                                        'module'    => 'msoffice', 
     963                                                        'mime_type' => 'application/octet-stream', 
     964                                                        'fail_id3'  => 'ERROR', 
     965                                                        'fail_ape'  => 'ERROR', 
     966                                                ), 
     967                        ); 
     968                } 
     969 
     970                return $format_info; 
     971        } 
     972 
     973 
     974 
     975        function GetFileFormat(&$filedata, $filename='') { 
     976                // this function will determine the format of a file based on usually 
     977                // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG, 
     978                // and in the case of ISO CD image, 6 bytes offset 32kb from the start 
     979                // of the file). 
     980 
     981                // Identify file format - loop through $format_info and detect with reg expr 
     982                foreach ($this->GetFileFormatArray() as $format_name => $info) { 
     983                        // Using preg_match() instead of ereg() - much faster 
     984                        // The /s switch on preg_match() forces preg_match() NOT to treat 
     985                        // newline (0x0A) characters as special chars but do a binary match 
     986                        if (preg_match('/'.$info['pattern'].'/s', $filedata)) { 
     987                                $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; 
     988                                return $info; 
     989                        } 
     990                } 
     991 
     992 
     993                if (preg_match('/\.mp[123a]$/i', $filename)) { 
     994                        // Too many mp3 encoders on the market put gabage in front of mpeg files 
     995                        // use assume format on these if format detection failed 
     996                        $GetFileFormatArray = $this->GetFileFormatArray(); 
     997                        $info = $GetFileFormatArray['mp3']; 
     998                        $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; 
     999                        return $info; 
     1000                } 
     1001 
     1002                return false; 
     1003        } 
     1004 
     1005 
     1006        // converts array to $encoding charset from $this->encoding 
     1007        function CharConvert(&$array, $encoding) { 
     1008 
     1009                // identical encoding - end here 
     1010                if ($encoding == $this->encoding) { 
     1011                        return; 
     1012                } 
     1013 
     1014                // loop thru array 
     1015                foreach ($array as $key => $value) { 
     1016 
     1017                        // go recursive 
     1018                        if (is_array($value)) { 
     1019                                $this->CharConvert($array[$key], $encoding); 
     1020                        } 
     1021 
     1022                        // convert string 
     1023                        elseif (is_string($value)) { 
     1024                                $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value)); 
     1025                        } 
     1026                } 
     1027        } 
     1028 
     1029 
     1030        function HandleAllTags() { 
     1031 
     1032                // key name => array (tag name, character encoding) 
     1033                static $tags; 
     1034                if (empty($tags)) { 
     1035                        $tags = array( 
     1036                                'asf'       => array('asf'           , 'UTF-16LE'), 
     1037                                'midi'      => array('midi'          , 'ISO-8859-1'), 
     1038                                'nsv'       => array('nsv'           , 'ISO-8859-1'), 
     1039                                'ogg'       => array('vorbiscomment' , 'UTF-8'), 
     1040                                'png'       => array('png'           , 'UTF-8'), 
     1041                                'tiff'      => array('tiff'          , 'ISO-8859-1'), 
     1042                                'quicktime' => array('quicktime'     , 'ISO-8859-1'), 
     1043                                'real'      => array('real'          , 'ISO-8859-1'), 
     1044                                'vqf'       => array('vqf'           , 'ISO-8859-1'), 
     1045                                'zip'       => array('zip'           , 'ISO-8859-1'), 
     1046                                'riff'      => array('riff'          , 'ISO-8859-1'), 
     1047                                'lyrics3'   => array('lyrics3'       , 'ISO-8859-1'), 
     1048                                'id3v1'     => array('id3v1'         , $this->encoding_id3v1), 
     1049                                'id3v2'     => array('id3v2'         , 'UTF-8'), // not according to the specs (every frame can have a different encoding), but getID3() force-converts all encodings to UTF-8 
     1050                                'ape'       => array('ape'           , 'UTF-8') 
     1051                        ); 
     1052                } 
     1053 
     1054                // loop thru comments array 
     1055                foreach ($tags as $comment_name => $tagname_encoding_array) { 
     1056                        list($tag_name, $encoding) = $tagname_encoding_array; 
     1057 
     1058                        // fill in default encoding type if not already present 
     1059                        if (isset($this->info[$comment_name]) && !isset($this->info[$comment_name]['encoding'])) { 
     1060                                $this->info[$comment_name]['encoding'] = $encoding; 
     1061                        } 
     1062 
     1063                        // copy comments if key name set 
     1064                        if (!empty($this->info[$comment_name]['comments'])) { 
     1065 
     1066                                foreach ($this->info[$comment_name]['comments'] as $tag_key => $valuearray) { 
     1067                                        foreach ($valuearray as $key => $value) { 
     1068                                                if (strlen(trim($value)) > 0) { 
     1069                                                        $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; // do not trim!! Unicode characters will get mangled if trailing nulls are removed! 
     1070                                                } 
     1071                                        } 
     1072                                } 
     1073 
     1074                                if (!isset($this->info['tags'][$tag_name])) { 
     1075                                        // comments are set but contain nothing but empty strings, so skip 
     1076                                        continue; 
     1077                                } 
     1078 
     1079                                if ($this->option_tags_html) { 
     1080                                        foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) { 
     1081                                                foreach ($valuearray as $key => $value) { 
     1082                                                        if (is_string($value)) { 
     1083                                                                //$this->info['tags_html'][$tag_name][$tag_key][$key] = getid3_lib::MultiByteCharString2HTML($value, $encoding); 
     1084                                                                $this->info['tags_html'][$tag_name][$tag_key][$key] = str_replace('&#0;', '', getid3_lib::MultiByteCharString2HTML($value, $encoding)); 
     1085                                                        } else { 
     1086                                                                $this->info['tags_html'][$tag_name][$tag_key][$key] = $value; 
     1087                                                        } 
     1088                                                } 
     1089                                        } 
     1090                                } 
     1091 
     1092                                $this->CharConvert($this->info['tags'][$tag_name], $encoding);           // only copy gets converted! 
     1093                        } 
     1094 
     1095                } 
     1096                return true; 
     1097        } 
     1098 
     1099 
     1100        function getHashdata($algorithm) { 
     1101                switch ($algorithm) { 
     1102                        case 'md5': 
     1103                        case 'sha1': 
     1104                                break; 
     1105 
     1106                        default: 
     1107                                return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()'); 
     1108                                break; 
     1109                } 
     1110 
     1111                if ((@$this->info['fileformat'] == 'ogg') && (@$this->info['audio']['dataformat'] == 'vorbis')) { 
     1112 
     1113                        // We cannot get an identical md5_data value for Ogg files where the comments 
     1114                        // span more than 1 Ogg page (compared to the same audio data with smaller 
     1115                        // comments) using the normal getID3() method of MD5'ing the data between the 
     1116                        // end of the comments and the end of the file (minus any trailing tags), 
     1117                        // because the page sequence numbers of the pages that the audio data is on 
     1118                        // do not match. Under normal circumstances, where comments are smaller than 
     1119                        // the nominal 4-8kB page size, then this is not a problem, but if there are 
     1120                        // very large comments, the only way around it is to strip off the comment 
     1121                        // tags with vorbiscomment and MD5 that file. 
     1122                        // This procedure must be applied to ALL Ogg files, not just the ones with 
     1123                        // comments larger than 1 page, because the below method simply MD5's the 
     1124                        // whole file with the comments stripped, not just the portion after the 
     1125                        // comments block (which is the standard getID3() method. 
     1126 
     1127                        // The above-mentioned problem of comments spanning multiple pages and changing 
     1128                        // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but 
     1129                        // currently vorbiscomment only works on OggVorbis files. 
     1130 
     1131                        if ((bool) ini_get('safe_mode')) { 
     1132 
     1133                                $this->info['warning'][] = 'Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)'; 
     1134                                $this->info[$algorithm.'_data']  = false; 
     1135 
     1136                        } else { 
     1137 
     1138                                // Prevent user from aborting script 
     1139                                $old_abort = ignore_user_abort(true); 
     1140 
     1141                                // Create empty file 
     1142                                $empty = tempnam('*', 'getID3'); 
     1143                                touch($empty); 
     1144 
     1145 
     1146                                // Use vorbiscomment to make temp file without comments 
     1147                                $temp = tempnam('*', 'getID3'); 
     1148                                $file = $this->info['filenamepath']; 
     1149 
     1150                                if (GETID3_OS_ISWINDOWS) { 
     1151 
     1152                                        if (file_exists(GETID3_HELPERAPPSDIR.'vorbiscomment.exe')) { 
     1153 
     1154                                                $commandline = '"'.GETID3_HELPERAPPSDIR.'vorbiscomment.exe" -w -c "'.$empty.'" "'.$file.'" "'.$temp.'"'; 
     1155                                                $VorbisCommentError = `$commandline`; 
     1156 
     1157                                        } else { 
     1158 
     1159                                                $VorbisCommentError = 'vorbiscomment.exe not found in '.GETID3_HELPERAPPSDIR; 
     1160 
     1161                                        } 
     1162 
     1163                                } else { 
     1164 
     1165                                        $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1'; 
     1166                                        $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1'; 
     1167                                        $VorbisCommentError = `$commandline`; 
     1168 
     1169                                } 
     1170 
     1171                                if (!empty($VorbisCommentError)) { 
     1172 
     1173                                        $this->info['warning'][]         = 'Failed making system call to vorbiscomment(.exe) - '.$algorithm.'_data will be incorrect. If vorbiscomment is unavailable, please download from http://www.vorbis.com/download.psp and put in the getID3() directory. Error returned: '.$VorbisCommentError; 
     1174                                        $this->info[$algorithm.'_data']  = false; 
     1175 
     1176                                } else { 
     1177 
     1178                                        // Get hash of newly created file 
     1179                                        switch ($algorithm) { 
     1180                                                case 'md5': 
     1181                                                        $this->info[$algorithm.'_data'] = getid3_lib::md5_file($temp); 
     1182                                                        break; 
     1183 
     1184                                                case 'sha1': 
     1185                                                        $this->info[$algorithm.'_data'] = getid3_lib::sha1_file($temp); 
     1186                                                        break; 
     1187                                        } 
     1188                                } 
     1189 
     1190                                // Clean up 
     1191                                unlink($empty); 
     1192                                unlink($temp); 
     1193 
     1194                                // Reset abort setting 
     1195                                ignore_user_abort($old_abort); 
     1196 
     1197                        } 
     1198 
     1199                } else { 
     1200 
     1201                        if (!empty($this->info['avdataoffset']) || (isset($this->info['avdataend']) && ($this->info['avdataend'] < $this->info['filesize']))) { 
     1202 
     1203                                // get hash from part of file 
     1204                                $this->info[$algorithm.'_data'] = getid3_lib::hash_data($this->info['filenamepath'], $this->info['avdataoffset'], $this->info['avdataend'], $algorithm); 
     1205 
     1206                        } else { 
     1207 
     1208                                // get hash from whole file 
     1209                                switch ($algorithm) { 
     1210                                        case 'md5': 
     1211                                                $this->info[$algorithm.'_data'] = getid3_lib::md5_file($this->info['filenamepath']); 
     1212                                                break; 
     1213 
     1214                                        case 'sha1': 
     1215                                                $this->info[$algorithm.'_data'] = getid3_lib::sha1_file($this->info['filenamepath']); 
     1216                                                break; 
     1217                                } 
     1218                        } 
     1219 
     1220                } 
     1221                return true; 
     1222        } 
     1223 
     1224 
     1225        function ChannelsBitratePlaytimeCalculations() { 
     1226 
     1227                // set channelmode on audio 
     1228                if (@$this->info['audio']['channels'] == '1') { 
     1229                        $this->info['audio']['channelmode'] = 'mono'; 
     1230                } elseif (@$this->info['audio']['channels'] == '2') { 
     1231                        $this->info['audio']['channelmode'] = 'stereo'; 
     1232                } 
     1233 
     1234                // Calculate combined bitrate - audio + video 
     1235                $CombinedBitrate  = 0; 
     1236                $CombinedBitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0); 
     1237                $CombinedBitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0); 
     1238                if (($CombinedBitrate > 0) && empty($this->info['bitrate'])) { 
     1239                        $this->info['bitrate'] = $CombinedBitrate; 
     1240                } 
     1241                //if ((isset($this->info['video']) && !isset($this->info['video']['bitrate'])) || (isset($this->info['audio']) && !isset($this->info['audio']['bitrate']))) { 
     1242                //      // for example, VBR MPEG video files cannot determine video bitrate: 
     1243                //      // should not set overall bitrate and playtime from audio bitrate only 
     1244                //      unset($this->info['bitrate']); 
     1245                //} 
     1246 
     1247                // video bitrate undetermined, but calculable 
     1248                if (isset($this->info['video']['dataformat']) && $this->info['video']['dataformat'] && (!isset($this->info['video']['bitrate']) || ($this->info['video']['bitrate'] == 0))) { 
     1249                        // if video bitrate not set 
     1250                        if (isset($this->info['audio']['bitrate']) && ($this->info['audio']['bitrate'] > 0) && ($this->info['audio']['bitrate'] == $this->info['bitrate'])) { 
     1251                                // AND if audio bitrate is set to same as overall bitrate 
     1252                                if (isset($this->info['playtime_seconds']) && ($this->info['playtime_seconds'] > 0)) { 
     1253                                        // AND if playtime is set 
     1254                                        if (isset($this->info['avdataend']) && isset($this->info['avdataoffset'])) { 
     1255                                                // AND if AV data offset start/end is known 
     1256                                                // THEN we can calculate the video bitrate 
     1257                                                $this->info['bitrate'] = round((($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']); 
     1258                                                $this->info['video']['bitrate'] = $this->info['bitrate'] - $this->info['audio']['bitrate']; 
     1259                                        } 
     1260                                } 
     1261                        } 
     1262                } 
     1263 
     1264                if ((!isset($this->info['playtime_seconds']) || ($this->info['playtime_seconds'] <= 0)) && !empty($this->info['bitrate'])) { 
     1265                        $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate']; 
     1266                } 
     1267 
     1268                if (!isset($this->info['bitrate']) && !empty($this->info['playtime_seconds'])) { 
     1269                        $this->info['bitrate'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']; 
     1270                } 
     1271//echo '<pre>'; 
     1272//var_dump($this->info['bitrate']); 
     1273//var_dump($this->info['audio']['bitrate']); 
     1274//var_dump($this->info['video']['bitrate']); 
     1275//echo '</pre>'; 
     1276                if (isset($this->info['bitrate']) && empty($this->info['audio']['bitrate']) && empty($this->info['video']['bitrate'])) { 
     1277                        if (isset($this->info['audio']['dataformat']) && empty($this->info['video']['resolution_x'])) { 
     1278                                // audio only 
     1279                                $this->info['audio']['bitrate'] = $this->info['bitrate']; 
     1280                        } elseif (isset($this->info['video']['resolution_x']) && empty($this->info['audio']['dataformat'])) { 
     1281                                // video only 
     1282                                $this->info['video']['bitrate'] = $this->info['bitrate']; 
     1283                        } 
     1284                } 
     1285 
     1286                // Set playtime string 
     1287                if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { 
     1288                        $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']); 
     1289                } 
     1290        } 
     1291 
     1292 
     1293        function CalculateCompressionRatioVideo() { 
     1294                if (empty($this->info['video'])) { 
     1295                        return false; 
     1296                } 
     1297                if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) { 
     1298                        return false; 
     1299                } 
     1300                if (empty($this->info['video']['bits_per_sample'])) { 
     1301                        return false; 
     1302                } 
     1303 
     1304                switch ($this->info['video']['dataformat']) { 
     1305                        case 'bmp': 
     1306                        case 'gif': 
     1307                        case 'jpeg': 
     1308                        case 'jpg': 
     1309                        case 'png': 
     1310                        case 'tiff': 
     1311                                $FrameRate = 1; 
     1312                                $PlaytimeSeconds = 1; 
     1313                                $BitrateCompressed = $this->info['filesize'] * 8; 
     1314                                break; 
     1315 
     1316                        default: 
     1317                                if (!empty($this->info['video']['frame_rate'])) { 
     1318                                        $FrameRate = $this->info['video']['frame_rate']; 
     1319                                } else { 
     1320                                        return false; 
     1321                                } 
     1322                                if (!empty($this->info['playtime_seconds'])) { 
     1323                                        $PlaytimeSeconds = $this->info['playtime_seconds']; 
     1324                                } else { 
     1325                                        return false; 
     1326                                } 
     1327                                if (!empty($this->info['video']['bitrate'])) { 
     1328                                        $BitrateCompressed = $this->info['video']['bitrate']; 
     1329                                } else { 
     1330                                        return false; 
     1331                                } 
     1332                                break; 
     1333                } 
     1334                $BitrateUncompressed = $this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $FrameRate; 
     1335 
     1336                $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; 
     1337                return true; 
     1338        } 
     1339 
     1340 
     1341        function CalculateCompressionRatioAudio() { 
     1342                if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate'])) { 
     1343                        return false; 
     1344                } 
     1345                $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16)); 
     1346 
     1347                if (!empty($this->info['audio']['streams'])) { 
     1348                        foreach ($this->info['audio']['streams'] as $streamnumber => $streamdata) { 
     1349                                if (!empty($streamdata['bitrate']) && !empty($streamdata['channels']) && !empty($streamdata['sample_rate'])) { 
     1350                                        $this->info['audio']['streams'][$streamnumber]['compression_ratio'] = $streamdata['bitrate'] / ($streamdata['channels'] * $streamdata['sample_rate'] * (!empty($streamdata['bits_per_sample']) ? $streamdata['bits_per_sample'] : 16)); 
     1351                                } 
     1352                        } 
     1353                } 
     1354                return true; 
     1355        } 
     1356 
     1357 
     1358        function CalculateReplayGain() { 
     1359                if (isset($this->info['replay_gain'])) { 
     1360                        $this->info['replay_gain']['reference_volume'] = 89; 
     1361                        if (isset($this->info['replay_gain']['track']['adjustment'])) { 
     1362                                $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; 
     1363                        } 
     1364                        if (isset($this->info['replay_gain']['album']['adjustment'])) { 
     1365                                $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment']; 
     1366                        } 
     1367 
     1368                        if (isset($this->info['replay_gain']['track']['peak'])) { 
     1369                                $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['track']['peak']); 
     1370                        } 
     1371                        if (isset($this->info['replay_gain']['album']['peak'])) { 
     1372                                $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['album']['peak']); 
     1373                        } 
     1374                } 
     1375                return true; 
     1376        } 
     1377 
     1378        function ProcessAudioStreams() { 
     1379                if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) { 
     1380                        if (!isset($this->info['audio']['streams'])) { 
     1381                                foreach ($this->info['audio'] as $key => $value) { 
     1382                                        if ($key != 'streams') { 
     1383                                                $this->info['audio']['streams'][0][$key] = $value; 
     1384                                        } 
     1385                                } 
     1386                        } 
     1387                } 
     1388                return true; 
     1389        } 
     1390 
     1391        function getid3_tempnam() { 
     1392                return tempnam($this->tempdir, 'gI3'); 
     1393        } 
     1394 
    11401395} 
    11411396 
    1142  
    1143 abstract class getid3_handler 
    1144 { 
    1145  
    1146     protected $getid3;                          // pointer 
    1147  
    1148     protected $data_string_flag = false;        // analyzing filepointer or string 
    1149     protected $data_string;                     // string to analyze 
    1150     protected $data_string_position = 0;        // seek position in string 
    1151  
    1152  
    1153     public function __construct(getID3 $getid3) { 
    1154  
    1155         $this->getid3 = $getid3; 
    1156     } 
    1157  
    1158  
    1159     // Analyze from file pointer 
    1160     abstract public function Analyze(); 
    1161  
    1162  
    1163  
    1164     // Analyze from string instead 
    1165     public function AnalyzeString(&$string) { 
    1166  
    1167         // Enter string mode 
    1168         $this->data_string_flag = true; 
    1169         $this->data_string      = $string; 
    1170  
    1171         // Save info 
    1172         $saved_avdataoffset = $this->getid3->info['avdataoffset']; 
    1173         $saved_avdataend    = $this->getid3->info['avdataend']; 
    1174         $saved_filesize     = $this->getid3->info['filesize']; 
    1175  
    1176         // Reset some info 
    1177         $this->getid3->info['avdataoffset'] = 0; 
    1178         $this->getid3->info['avdataend']    = $this->getid3->info['filesize'] = strlen($string); 
    1179  
    1180         // Analyze 
    1181         $this->Analyze(); 
    1182  
    1183         // Restore some info 
    1184         $this->getid3->info['avdataoffset'] = $saved_avdataoffset; 
    1185         $this->getid3->info['avdataend']    = $saved_avdataend; 
    1186         $this->getid3->info['filesize']     = $saved_filesize; 
    1187  
    1188         // Exit string mode 
    1189         $this->data_string_flag = false; 
    1190     } 
    1191  
    1192  
    1193     protected function ftell() { 
    1194  
    1195         if ($this->data_string_flag) { 
    1196             return $this->data_string_position; 
    1197         } 
    1198         return ftell($this->getid3->fp); 
    1199     } 
    1200  
    1201  
    1202     protected function fread($bytes) { 
    1203  
    1204         if ($this->data_string_flag) { 
    1205             $this->data_string_position += $bytes; 
    1206             return substr($this->data_string, $this->data_string_position - $bytes, $bytes); 
    1207         } 
    1208         return fread($this->getid3->fp, $bytes); 
    1209     } 
    1210  
    1211  
    1212     protected function fseek($bytes, $whence = SEEK_SET) { 
    1213  
    1214         if ($this->data_string_flag) { 
    1215             switch ($whence) { 
    1216                 case SEEK_SET: 
    1217                     $this->data_string_position = $bytes; 
    1218                     return; 
    1219  
    1220                 case SEEK_CUR: 
    1221                     $this->data_string_position += $bytes; 
    1222                     return; 
    1223  
    1224                 case SEEK_END: 
    1225                     $this->data_string_position = strlen($this->data_string) + $bytes; 
    1226                     return; 
    1227             } 
    1228         } 
    1229         return fseek($this->getid3->fp, $bytes, $whence); 
    1230     } 
    1231  
    1232 } 
    1233  
    1234  
    1235  
    1236  
    1237 abstract class getid3_handler_write 
    1238 { 
    1239     protected $filename; 
    1240     protected $user_abort; 
    1241  
    1242     private $fp_lock; 
    1243     private $owner; 
    1244     private $group; 
    1245     private $perms; 
    1246  
    1247  
    1248     public function __construct($filename) { 
    1249  
    1250         if (!file_exists($filename)) { 
    1251             throw new getid3_exception('File does not exist: "' . $filename . '"'); 
    1252         } 
    1253  
    1254         if (!is_writeable($filename)) { 
    1255             throw new getid3_exception('File is not writeable: "' . $filename . '"'); 
    1256         } 
    1257  
    1258         if (!is_writeable(dirname($filename))) { 
    1259             throw new getid3_exception('Directory is not writeable: ' . dirname($filename) . ' (need to write lock file).'); 
    1260         } 
    1261  
    1262         $this->user_abort = ignore_user_abort(true); 
    1263  
    1264         $this->fp_lock = fopen($filename . '.getid3.lock', 'w'); 
    1265         flock($this->fp_lock, LOCK_EX); 
    1266  
    1267         $this->filename = $filename; 
    1268     } 
    1269  
    1270  
    1271     public function __destruct() { 
    1272  
    1273         flock($this->fp_lock, LOCK_UN); 
    1274         fclose($this->fp_lock); 
    1275         unlink($this->filename . '.getid3.lock'); 
    1276  
    1277         ignore_user_abort($this->user_abort); 
    1278     } 
    1279      
    1280      
    1281     protected function save_permissions() { 
    1282          
    1283         $this->owner = fileowner($this->filename); 
    1284         $this->group = filegroup($this->filename); 
    1285         $this->perms = fileperms($this->filename); 
    1286     } 
    1287      
    1288      
    1289     protected function restore_permissions() { 
    1290          
    1291         @chown($this->filename, $this->owner); 
    1292         @chgrp($this->filename, $this->group); 
    1293         @chmod($this->filename, $this->perms); 
    1294     } 
    1295  
    1296  
    1297     abstract public function read(); 
    1298  
    1299     abstract public function write(); 
    1300  
    1301     abstract public function remove(); 
    1302  
    1303 } 
    1304  
    1305  
    1306  
    1307  
    1308 class getid3_exception extends Exception 
    1309 { 
    1310     public $message; 
    1311  
    1312 } 
    1313  
    1314  
    1315  
    1316  
    1317 class getid3_lib 
    1318 { 
    1319  
    1320     // Convert Little Endian byte string to int - max 32 bits 
    1321     public static function LittleEndian2Int($byte_word, $signed = false) { 
    1322  
    1323         return getid3_lib::BigEndian2Int(strrev($byte_word), $signed); 
    1324     } 
    1325  
    1326  
    1327  
    1328     // Convert number to Little Endian byte string 
    1329     public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) { 
    1330         $intstring = ''; 
    1331         while ($number > 0) { 
    1332             if ($synchsafe) { 
    1333                 $intstring = $intstring.chr($number & 127); 
    1334                 $number >>= 7; 
    1335             } else { 
    1336                 $intstring = $intstring.chr($number & 255); 
    1337                 $number >>= 8; 
    1338             } 
    1339         } 
    1340         return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT); 
    1341     } 
    1342  
    1343  
    1344  
    1345     // Convert Big Endian byte string to int - max 32 bits 
    1346     public static function BigEndian2Int($byte_word, $signed = false) { 
    1347  
    1348         $int_value = 0; 
    1349         $byte_wordlen = strlen($byte_word); 
    1350  
    1351         for ($i = 0; $i < $byte_wordlen; $i++) { 
    1352             $int_value += ord($byte_word{$i}) * pow(256, ($byte_wordlen - 1 - $i)); 
    1353         } 
    1354  
    1355         if ($signed) { 
    1356             $sign_mask_bit = 0x80 << (8 * ($byte_wordlen - 1)); 
    1357             if ($int_value & $sign_mask_bit) { 
    1358                 $int_value = 0 - ($int_value & ($sign_mask_bit - 1)); 
    1359             } 
    1360         } 
    1361  
    1362         return $int_value; 
    1363     } 
    1364  
    1365  
    1366  
    1367     // Convert Big Endian byte sybc safe string to int - max 32 bits 
    1368     public static function BigEndianSyncSafe2Int($byte_word) { 
    1369  
    1370         $int_value = 0; 
    1371         $byte_wordlen = strlen($byte_word); 
    1372  
    1373         // disregard MSB, effectively 7-bit bytes 
    1374         for ($i = 0; $i < $byte_wordlen; $i++) { 
    1375             $int_value = $int_value | (ord($byte_word{$i}) & 0x7F) << (($byte_wordlen - 1 - $i) * 7); 
    1376         } 
    1377         return $int_value; 
    1378     } 
    1379  
    1380  
    1381  
    1382     // Convert Big Endian byte string to bit string 
    1383     public static function BigEndian2Bin($byte_word) { 
    1384  
    1385         $bin_value = ''; 
    1386         $byte_wordlen = strlen($byte_word); 
    1387         for ($i = 0; $i < $byte_wordlen; $i++) { 
    1388             $bin_value .= str_pad(decbin(ord($byte_word{$i})), 8, '0', STR_PAD_LEFT); 
    1389         } 
    1390         return $bin_value; 
    1391     } 
    1392  
    1393  
    1394  
    1395     public static function BigEndian2Float($byte_word) { 
    1396  
    1397                 // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic 
    1398                 // http://www.psc.edu/general/software/packages/ieee/ieee.html 
    1399                 // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html 
    1400  
    1401                 $bit_word = getid3_lib::BigEndian2Bin($byte_word); 
    1402                 if (!$bit_word) { 
    1403             return 0; 
    1404         } 
    1405                 $sign_bit = $bit_word{0}; 
    1406  
    1407                 switch (strlen($byte_word) * 8) { 
    1408                         case 32: 
    1409                                 $exponent_bits = 8; 
    1410                                 $fraction_bits = 23; 
    1411                                 break; 
    1412  
    1413                         case 64: 
    1414                                 $exponent_bits = 11; 
    1415                                 $fraction_bits = 52; 
    1416                                 break; 
    1417  
    1418                         case 80: 
    1419                                 // 80-bit Apple SANE format 
    1420                                 // http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/ 
    1421                                 $exponent_string = substr($bit_word, 1, 15); 
    1422                                 $is_normalized = intval($bit_word{16}); 
    1423                                 $fraction_string = substr($bit_word, 17, 63); 
    1424                                 $exponent = pow(2, getid3_lib::Bin2Dec($exponent_string) - 16383); 
    1425                                 $fraction = $is_normalized + getid3_lib::DecimalBinary2Float($fraction_string); 
    1426                                 $float_value = $exponent * $fraction; 
    1427                                 if ($sign_bit == '1') { 
    1428                                         $float_value *= -1; 
    1429                                 } 
    1430                                 return $float_value; 
    1431                                 break; 
    1432  
    1433                         default: 
    1434                                 return false; 
    1435                                 break; 
    1436                 } 
    1437                 $exponent_string = substr($bit_word, 1, $exponent_bits); 
    1438                 $fraction_string = substr($bit_word, $exponent_bits + 1, $fraction_bits); 
    1439                 $exponent = bindec($exponent_string); 
    1440                 $fraction = bindec($fraction_string); 
    1441  
    1442                 if (($exponent == (pow(2, $exponent_bits) - 1)) && ($fraction != 0)) { 
    1443                         // Not a Number 
    1444                         $float_value = false; 
    1445                 } elseif (($exponent == (pow(2, $exponent_bits) - 1)) && ($fraction == 0)) { 
    1446                         if ($sign_bit == '1') { 
    1447                                 $float_value = '-infinity'; 
    1448                         } else { 
    1449                                 $float_value = '+infinity'; 
    1450                         } 
    1451                 } elseif (($exponent == 0) && ($fraction == 0)) { 
    1452                         if ($sign_bit == '1') { 
    1453                                 $float_value = -0; 
    1454                         } else { 
    1455                                 $float_value = 0; 
    1456                         } 
    1457                         $float_value = ($sign_bit ? 0 : -0); 
    1458                 } elseif (($exponent == 0) && ($fraction != 0)) { 
    1459                         // These are 'unnormalized' values 
    1460                         $float_value = pow(2, (-1 * (pow(2, $exponent_bits - 1) - 2))) * getid3_lib::DecimalBinary2Float($fraction_string); 
    1461                         if ($sign_bit == '1') { 
    1462                                 $float_value *= -1; 
    1463                         } 
    1464                 } elseif ($exponent != 0) { 
    1465                         $float_value = pow(2, ($exponent - (pow(2, $exponent_bits - 1) - 1))) * (1 + getid3_lib::DecimalBinary2Float($fraction_string)); 
    1466                         if ($sign_bit == '1') { 
    1467                                 $float_value *= -1; 
    1468                         } 
    1469                 } 
    1470                 return (float) $float_value; 
    1471         } 
    1472  
    1473  
    1474  
    1475         public static function LittleEndian2Float($byte_word) { 
    1476  
    1477                 return getid3_lib::BigEndian2Float(strrev($byte_word)); 
    1478         } 
    1479  
    1480  
    1481  
    1482         public static function DecimalBinary2Float($binary_numerator) { 
    1483                 $numerator   = bindec($binary_numerator); 
    1484                 $denominator = bindec('1'.str_repeat('0', strlen($binary_numerator))); 
    1485                 return ($numerator / $denominator); 
    1486         } 
    1487  
    1488  
    1489         public static function PrintHexBytes($string, $hex=true, $spaces=true, $html_safe=true) { 
    1490  
    1491         $return_string = ''; 
    1492         for ($i = 0; $i < strlen($string); $i++) { 
    1493             if ($hex) { 
    1494                 $return_string .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT); 
    1495             } else { 
    1496                 $return_string .= ' '.(ereg("[\x20-\x7E]", $string{$i}) ? $string{$i} : '¤'); 
    1497             } 
    1498             if ($spaces) { 
    1499                 $return_string .= ' '; 
    1500             } 
    1501         } 
    1502         if ($html_safe) { 
    1503             $return_string = htmlentities($return_string); 
    1504         } 
    1505         return $return_string; 
    1506     } 
    1507  
    1508  
    1509  
    1510     // Process header data string - read several values with algorithm and add to target 
    1511     //   algorithm is one one the getid3_lib::Something2Something() function names 
    1512     //   parts_array is  index => length    -  $target[index] = algorithm(substring(data)) 
    1513     //   - OR just substring(data) if length is negative! 
    1514     //  indexes == 'IGNORE**' are ignored 
    1515  
    1516     public static function ReadSequence($algorithm, &$target, &$data, $offset, $parts_array) { 
    1517  
    1518         // Loop thru $parts_array 
    1519         foreach ($parts_array as $target_string => $length) { 
    1520  
    1521             // Add to target 
    1522             if (!strstr($target_string, 'IGNORE')) { 
    1523  
    1524                 // substr(....length) 
    1525                 if ($length < 0) { 
    1526                     $target[$target_string] = substr($data, $offset, -$length); 
    1527                 } 
    1528  
    1529                 // algorithm(substr(...length)) 
    1530                 else { 
    1531                     $target[$target_string] = getid3_lib::$algorithm(substr($data, $offset, $length)); 
    1532                 } 
    1533             } 
    1534  
    1535             // Move pointer 
    1536             $offset += abs($length); 
    1537         } 
    1538     } 
    1539  
    1540 } 
    1541  
    1542  
    1543  
    1544 class getid3_lib_replaygain 
    1545 { 
    1546  
    1547     public static function NameLookup($name_code) { 
    1548  
    1549         static $lookup = array ( 
    1550             0 => 'not set', 
    1551             1 => 'Track Gain Adjustment', 
    1552             2 => 'Album Gain Adjustment' 
    1553         ); 
    1554  
    1555         return @$lookup[$name_code]; 
    1556     } 
    1557  
    1558  
    1559  
    1560     public static function OriginatorLookup($originator_code) { 
    1561  
    1562         static $lookup = array ( 
    1563             0 => 'unspecified', 
    1564             1 => 'pre-set by artist/producer/mastering engineer', 
    1565             2 => 'set by user', 
    1566             3 => 'determined automatically' 
    1567         ); 
    1568  
    1569         return @$lookup[$originator_code]; 
    1570     } 
    1571  
    1572  
    1573  
    1574     public static function AdjustmentLookup($raw_adjustment, $sign_bit) { 
    1575  
    1576         return (float)$raw_adjustment / 10 * ($sign_bit == 1 ? -1 : 1); 
    1577     } 
    1578  
    1579  
    1580  
    1581     public static function GainString($name_code, $originator_code, $replaygain) { 
    1582  
    1583         $sign_bit = $replaygain < 0 ? 1 : 0; 
    1584  
    1585         $stored_replaygain = intval(round($replaygain * 10)); 
    1586         $gain_string  = str_pad(decbin($name_code), 3, '0', STR_PAD_LEFT); 
    1587         $gain_string .= str_pad(decbin($originator_code), 3, '0', STR_PAD_LEFT); 
    1588         $gain_string .= $sign_bit; 
    1589         $gain_string .= str_pad(decbin($stored_replaygain), 9, '0', STR_PAD_LEFT); 
    1590  
    1591         return $gain_string; 
    1592     } 
    1593  
    1594 } 
    1595  
    1596  
    1597  
    1598  
    15991397?> 
  • extensions/charlies_content/getid3/getid3/module.archive.gzip.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | module.archive.gzip.php                                              | 
    18 // | module for analyzing GZIP files                                      | 
    19 // | dependencies: PHP compiled with zlib support (optional)              | 
    20 // +----------------------------------------------------------------------+ 
    21 // | Module originally written by Mike Mozolin <teddybearØmail*ru>        | 
    22 // +----------------------------------------------------------------------+ 
    23 // 
    24 // $Id$ 
    25  
    26          
    27          
    28 class getid3_gzip extends getid3_handler 
    29 { 
    30  
    31     // public: Optional file list - disable for speed. 
    32     public $option_gzip_parse_contents = true; // decode gzipped files, if possible, and parse recursively (.tar.gz for example) 
    33  
    34      
    35     // Reads the gzip-file 
    36     function Analyze() { 
    37  
    38         $info = &$this->getid3->info; 
    39  
    40         $info['fileformat'] = 'gzip'; 
    41  
    42         $start_length = 10; 
    43         $unpack_header = 'a1id1/a1id2/a1cmethod/a1flags/a4mtime/a1xflags/a1os'; 
    44          
    45         //+---+---+---+---+---+---+---+---+---+---+ 
    46         //|ID1|ID2|CM |FLG|     MTIME     |XFL|OS | 
    47         //+---+---+---+---+---+---+---+---+---+---+ 
    48          
    49         @fseek($this->getid3->fp, 0); 
    50         $buffer = @fread($this->getid3->fp, $info['filesize']); 
    51  
    52         $arr_members = explode("\x1F\x8B\x08", $buffer); 
    53          
    54         while (true) { 
    55             $is_wrong_members = false; 
    56             $num_members = intval(count($arr_members)); 
    57             for ($i = 0; $i < $num_members; $i++) { 
    58                 if (strlen($arr_members[$i]) == 0) { 
    59                     continue; 
    60                 } 
    61                 $buf = "\x1F\x8B\x08".$arr_members[$i]; 
    62  
    63                 $attr = unpack($unpack_header, substr($buf, 0, $start_length)); 
    64                 if (!$this->get_os_type(ord($attr['os']))) { 
    65          
    66                     // Merge member with previous if wrong OS type 
    67                     $arr_members[$i - 1] .= $buf; 
    68                     $arr_members[$i] = ''; 
    69                     $is_wrong_members = true; 
    70                     continue; 
    71                 } 
    72             } 
    73             if (!$is_wrong_members) { 
    74                 break; 
    75             } 
    76         } 
    77  
    78         $fpointer = 0; 
    79         $idx = 0; 
    80         for ($i = 0; $i < $num_members; $i++) { 
    81             if (strlen($arr_members[$i]) == 0) { 
    82                 continue; 
    83             } 
    84             $info_gzip_member_header_idx = &$info['gzip']['member_header'][++$idx]; 
    85  
    86             $buff = "\x1F\x8B\x08".$arr_members[$i]; 
    87  
    88             $attr = unpack($unpack_header, substr($buff, 0, $start_length)); 
    89             $info_gzip_member_header_idx['filemtime']      = getid3_lib::LittleEndian2Int($attr['mtime']); 
    90             $info_gzip_member_header_idx['raw']['id1']     = ord($attr['cmethod']); 
    91             $info_gzip_member_header_idx['raw']['id2']     = ord($attr['cmethod']); 
    92             $info_gzip_member_header_idx['raw']['cmethod'] = ord($attr['cmethod']); 
    93             $info_gzip_member_header_idx['raw']['os']      = ord($attr['os']); 
    94             $info_gzip_member_header_idx['raw']['xflags']  = ord($attr['xflags']); 
    95             $info_gzip_member_header_idx['raw']['flags']   = ord($attr['flags']); 
    96  
    97             $info_gzip_member_header_idx['flags']['crc16']    = (bool) ($info_gzip_member_header_idx['raw']['flags'] & 0x02); 
    98             $info_gzip_member_header_idx['flags']['extra']    = (bool) ($info_gzip_member_header_idx['raw']['flags'] & 0x04); 
    99             $info_gzip_member_header_idx['flags']['filename'] = (bool) ($info_gzip_member_header_idx['raw']['flags'] & 0x08); 
    100             $info_gzip_member_header_idx['flags']['comment']  = (bool) ($info_gzip_member_header_idx['raw']['flags'] & 0x10); 
    101  
    102             $info_gzip_member_header_idx['compression'] = $this->get_xflag_type($info_gzip_member_header_idx['raw']['xflags']); 
    103  
    104             $info_gzip_member_header_idx['os'] = $this->get_os_type($info_gzip_member_header_idx['raw']['os']); 
    105             if (!$info_gzip_member_header_idx['os']) { 
    106                 $info['error'][] = 'Read error on gzip file'; 
    107                 return false; 
    108             } 
    109  
    110             $fpointer = 10; 
    111             $arr_xsubfield = array (); 
    112              
    113             // bit 2 - FLG.FEXTRA 
    114             //+---+---+=================================+ 
    115             //| XLEN  |...XLEN bytes of "extra field"...| 
    116             //+---+---+=================================+ 
    117              
    118             if ($info_gzip_member_header_idx['flags']['extra']) { 
    119                 $w_xlen = substr($buff, $fpointer, 2); 
    120                 $xlen = getid3_lib::LittleEndian2Int($w_xlen); 
    121                 $fpointer += 2; 
    122  
    123                 $info_gzip_member_header_idx['raw']['xfield'] = substr($buff, $fpointer, $xlen); 
    124              
    125                 // Extra SubFields 
    126                 //+---+---+---+---+==================================+ 
    127                 //|SI1|SI2|  LEN  |... LEN bytes of subfield data ...| 
    128                 //+---+---+---+---+==================================+ 
    129              
    130                 $idx = 0; 
    131                 while (true) { 
    132                     if ($idx >= $xlen) { 
    133                         break; 
    134                     } 
    135                     $si1 = ord(substr($buff, $fpointer + $idx++, 1)); 
    136                     $si2 = ord(substr($buff, $fpointer + $idx++, 1)); 
    137                     if (($si1 == 0x41) && ($si2 == 0x70)) { 
    138                         $w_xsublen = substr($buff, $fpointer+$idx, 2); 
    139                         $xsublen = getid3_lib::LittleEndian2Int($w_xsublen); 
    140                         $idx += 2; 
    141                         $arr_xsubfield[] = substr($buff, $fpointer+$idx, $xsublen); 
    142                         $idx += $xsublen; 
    143                     } else { 
    144                         break; 
    145                     } 
    146                 } 
    147                 $fpointer += $xlen; 
    148             } 
    149              
    150             // bit 3 - FLG.FNAME 
    151             //+=========================================+ 
    152             //|...original file name, zero-terminated...| 
    153             //+=========================================+ 
    154             // GZIP files may have only one file, with no filename, so assume original filename is current filename without .gz 
    155              
    156             $info_gzip_member_header_idx['filename'] = eregi_replace('.gz$', '', @$info['filename']); 
    157             if ($info_gzip_member_header_idx['flags']['filename']) { 
    158                 while (true) { 
    159                     if (ord($buff[$fpointer]) == 0) { 
    160                         $fpointer++; 
    161                         break; 
    162                     } 
    163                     $info_gzip_member_header_idx['filename'] .= $buff[$fpointer]; 
    164                     $fpointer++; 
    165                 } 
    166             } 
    167              
    168             // bit 4 - FLG.FCOMMENT 
    169             //+===================================+ 
    170             //|...file comment, zero-terminated...| 
    171             //+===================================+ 
    172              
    173             if ($info_gzip_member_header_idx['flags']['comment']) { 
    174                 while (true) { 
    175                     if (ord($buff[$fpointer]) == 0) { 
    176                         $fpointer++; 
    177                         break; 
    178                     } 
    179                     $info_gzip_member_header_idx['comment'] .= $buff[$fpointer]; 
    180                     $fpointer++; 
    181                 } 
    182             } 
    183              
    184             // bit 1 - FLG.FHCRC 
    185             //+---+---+ 
    186             //| CRC16 | 
    187             //+---+---+ 
    188              
    189             if ($info_gzip_member_header_idx['flags']['crc16']) { 
    190                 $w_crc = substr($buff, $fpointer, 2); 
    191                 $info_gzip_member_header_idx['crc16'] = getid3_lib::LittleEndian2Int($w_crc); 
    192                 $fpointer += 2; 
    193             } 
    194              
    195             // bit 0 - FLG.FTEXT 
    196             //if ($info_gzip_member_header_idx['raw']['flags'] & 0x01) { 
    197             //  Ignored... 
    198             //} 
    199             // bits 5, 6, 7 - reserved 
    200  
    201             $info_gzip_member_header_idx['crc32']    = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 8, 4)); 
    202             $info_gzip_member_header_idx['filesize'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 4)); 
    203  
    204             if ($this->option_gzip_parse_contents) { 
    205  
    206                 // Try to inflate GZip 
    207                  
    208                 if (!function_exists('gzinflate')) { 
    209                     $this->getid3->warning('PHP does not have zlib support - contents not parsed.'); 
    210                     return true; 
    211                 } 
    212  
    213                 $csize = 0; 
    214                 $inflated = ''; 
    215                 $chkcrc32 = ''; 
    216  
    217                 $cdata = substr($buff, $fpointer); 
    218                 $cdata = substr($cdata, 0, strlen($cdata) - 8); 
    219                 $csize = strlen($cdata); 
    220                 $inflated = gzinflate($cdata); 
    221  
    222                 // Calculate CRC32 for inflated content 
    223                 $info_gzip_member_header_idx['crc32_valid'] = (bool) (sprintf('%u', crc32($inflated)) == $info_gzip_member_header_idx['crc32']); 
    224  
    225                  
    226                 //// Analyse contents 
    227                  
    228                 // write content to temp file 
    229                 if (($temp_file_name = tempnam('*', 'getID3'))  === false) { 
    230                     throw new getid3_exception('Unable to create temporary file.'); 
    231                 } 
    232  
    233                 if ($tmp = fopen($temp_file_name, 'wb')) { 
    234                     fwrite($tmp, $inflated); 
    235                     fclose($tmp); 
    236                      
    237                     // clone getid3 - we want same settings 
    238                     $clone = clone $this->getid3; 
    239                     unset($clone->info); 
    240                     try { 
    241                         $clone->Analyze($temp_file_name); 
    242                         $info_gzip_member_header_idx['parsed_content'] = $clone->info; 
    243                     } 
    244                     catch (getid3_exception $e) { 
    245                         // unable to parse contents 
    246                     } 
    247                      
    248                     unlink($temp_file_name); 
    249                 } 
    250              
    251                 // Unknown/unhandled format  
    252                 else { 
    253                                          
    254                 } 
    255             } 
    256         } 
    257         return true; 
    258     } 
    259  
    260  
    261     // Converts the OS type 
    262     public static function get_os_type($key) { 
    263         static $os_type = array ( 
    264             '0'   => 'FAT filesystem (MS-DOS, OS/2, NT/Win32)', 
    265             '1'   => 'Amiga', 
    266             '2'   => 'VMS (or OpenVMS)', 
    267             '3'   => 'Unix', 
    268             '4'   => 'VM/CMS', 
    269             '5'   => 'Atari TOS', 
    270             '6'   => 'HPFS filesystem (OS/2, NT)', 
    271             '7'   => 'Macintosh', 
    272             '8'   => 'Z-System', 
    273             '9'   => 'CP/M', 
    274             '10'  => 'TOPS-20', 
    275             '11'  => 'NTFS filesystem (NT)', 
    276             '12'  => 'QDOS', 
    277             '13'  => 'Acorn RISCOS', 
    278             '255' => 'unknown' 
    279         ); 
    280         return @$os_type[$key]; 
    281     } 
    282  
    283  
    284     // Converts the eXtra FLags 
    285     public static function get_xflag_type($key) { 
    286         static $xflag_type = array ( 
    287             '0' => 'unknown', 
    288             '2' => 'maximum compression', 
    289             '4' => 'fastest algorithm' 
    290         ); 
    291         return @$xflag_type[$key]; 
    292     } 
    293      
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7// See readme.txt for more details                             // 
     8///////////////////////////////////////////////////////////////// 
     9//                                                             // 
     10// module.archive.gzip.php                                     // 
     11// module for analyzing GZIP files                             // 
     12// dependencies: NONE                                          // 
     13//                                                            /// 
     14///////////////////////////////////////////////////////////////// 
     15//                                                             // 
     16// Module originally written by                                // 
     17//      Mike Mozolin <teddybearØmail*ru>                       // 
     18//                                                             // 
     19///////////////////////////////////////////////////////////////// 
     20 
     21 
     22class getid3_gzip { 
     23 
     24        // public: Optional file list - disable for speed. 
     25        var $option_gzip_parse_contents = false; // decode gzipped files, if possible, and parse recursively (.tar.gz for example) 
     26 
     27        function getid3_gzip(&$fd, &$ThisFileInfo) { 
     28                $ThisFileInfo['fileformat'] = 'gzip'; 
     29 
     30                $start_length = 10; 
     31                $unpack_header = 'a1id1/a1id2/a1cmethod/a1flags/a4mtime/a1xflags/a1os'; 
     32                //+---+---+---+---+---+---+---+---+---+---+ 
     33                //|ID1|ID2|CM |FLG|     MTIME     |XFL|OS | 
     34                //+---+---+---+---+---+---+---+---+---+---+ 
     35                @fseek($fd, 0); 
     36                $buffer = @fread($fd, $ThisFileInfo['filesize']); 
     37 
     38                $arr_members = explode("\x1F\x8B\x08", $buffer); 
     39                while (true) { 
     40                        $is_wrong_members = false; 
     41                        $num_members = intval(count($arr_members)); 
     42                        for ($i = 0; $i < $num_members; $i++) { 
     43                                if (strlen($arr_members[$i]) == 0) { 
     44                                        continue; 
     45                                } 
     46                                $buf = "\x1F\x8B\x08".$arr_members[$i]; 
     47 
     48                                $attr = unpack($unpack_header, substr($buf, 0, $start_length)); 
     49                                if (!$this->get_os_type(ord($attr['os']))) { 
     50                                        // Merge member with previous if wrong OS type 
     51                                        $arr_members[$i - 1] .= $buf; 
     52                                        $arr_members[$i] = ''; 
     53                                        $is_wrong_members = true; 
     54                                        continue; 
     55                                } 
     56                        } 
     57                        if (!$is_wrong_members) { 
     58                                break; 
     59                        } 
     60                } 
     61 
     62                $ThisFileInfo['gzip']['files'] = array(); 
     63 
     64                $fpointer = 0; 
     65                $idx = 0; 
     66                for ($i = 0; $i < $num_members; $i++) { 
     67                        if (strlen($arr_members[$i]) == 0) { 
     68                                continue; 
     69                        } 
     70                        $thisThisFileInfo = &$ThisFileInfo['gzip']['member_header'][++$idx]; 
     71 
     72                        $buff = "\x1F\x8B\x08".$arr_members[$i]; 
     73 
     74                        $attr = unpack($unpack_header, substr($buff, 0, $start_length)); 
     75                        $thisThisFileInfo['filemtime']      = getid3_lib::LittleEndian2Int($attr['mtime']); 
     76                        $thisThisFileInfo['raw']['id1']     = ord($attr['cmethod']); 
     77                        $thisThisFileInfo['raw']['id2']     = ord($attr['cmethod']); 
     78                        $thisThisFileInfo['raw']['cmethod'] = ord($attr['cmethod']); 
     79                        $thisThisFileInfo['raw']['os']      = ord($attr['os']); 
     80                        $thisThisFileInfo['raw']['xflags']  = ord($attr['xflags']); 
     81                        $thisThisFileInfo['raw']['flags']   = ord($attr['flags']); 
     82 
     83                        $thisThisFileInfo['flags']['crc16']    = (bool) ($thisThisFileInfo['raw']['flags'] & 0x02); 
     84                        $thisThisFileInfo['flags']['extra']    = (bool) ($thisThisFileInfo['raw']['flags'] & 0x04); 
     85                        $thisThisFileInfo['flags']['filename'] = (bool) ($thisThisFileInfo['raw']['flags'] & 0x08); 
     86                        $thisThisFileInfo['flags']['comment']  = (bool) ($thisThisFileInfo['raw']['flags'] & 0x10); 
     87 
     88                        $thisThisFileInfo['compression'] = $this->get_xflag_type($thisThisFileInfo['raw']['xflags']); 
     89 
     90                        $thisThisFileInfo['os'] = $this->get_os_type($thisThisFileInfo['raw']['os']); 
     91                        if (!$thisThisFileInfo['os']) { 
     92                                $ThisFileInfo['error'][] = 'Read error on gzip file'; 
     93                                return false; 
     94                        } 
     95 
     96                        $fpointer = 10; 
     97                        $arr_xsubfield = array(); 
     98                        // bit 2 - FLG.FEXTRA 
     99                        //+---+---+=================================+ 
     100                        //| XLEN  |...XLEN bytes of "extra field"...| 
     101                        //+---+---+=================================+ 
     102                        if ($thisThisFileInfo['flags']['extra']) { 
     103                                $w_xlen = substr($buff, $fpointer, 2); 
     104                                $xlen = getid3_lib::LittleEndian2Int($w_xlen); 
     105                                $fpointer += 2; 
     106 
     107                                $thisThisFileInfo['raw']['xfield'] = substr($buff, $fpointer, $xlen); 
     108                                // Extra SubFields 
     109                                //+---+---+---+---+==================================+ 
     110                                //|SI1|SI2|  LEN  |... LEN bytes of subfield data ...| 
     111                                //+---+---+---+---+==================================+ 
     112                                $idx = 0; 
     113                                while (true) { 
     114                                        if ($idx >= $xlen) { 
     115                                                break; 
     116                                        } 
     117                                        $si1 = ord(substr($buff, $fpointer + $idx++, 1)); 
     118                                        $si2 = ord(substr($buff, $fpointer + $idx++, 1)); 
     119                                        if (($si1 == 0x41) && ($si2 == 0x70)) { 
     120                                                $w_xsublen = substr($buff, $fpointer + $idx, 2); 
     121                                                $xsublen = getid3_lib::LittleEndian2Int($w_xsublen); 
     122                                                $idx += 2; 
     123                                                $arr_xsubfield[] = substr($buff, $fpointer + $idx, $xsublen); 
     124                                                $idx += $xsublen; 
     125                                        } else { 
     126                                                break; 
     127                                        } 
     128                                } 
     129                                $fpointer += $xlen; 
     130                        } 
     131                        // bit 3 - FLG.FNAME 
     132                        //+=========================================+ 
     133                        //|...original file name, zero-terminated...| 
     134                        //+=========================================+ 
     135                        // GZIP files may have only one file, with no filename, so assume original filename is current filename without .gz 
     136                        $thisThisFileInfo['filename'] = eregi_replace('.gz$', '', $ThisFileInfo['filename']); 
     137                        if ($thisThisFileInfo['flags']['filename']) { 
     138                                while (true) { 
     139                                        if (ord($buff[$fpointer]) == 0) { 
     140                                                $fpointer++; 
     141                                                break; 
     142                                        } 
     143                                        $thisThisFileInfo['filename'] .= $buff[$fpointer]; 
     144                                        $fpointer++; 
     145                                } 
     146                        } 
     147                        // bit 4 - FLG.FCOMMENT 
     148                        //+===================================+ 
     149                        //|...file comment, zero-terminated...| 
     150                        //+===================================+ 
     151                        if ($thisThisFileInfo['flags']['comment']) { 
     152                                while (true) { 
     153                                        if (ord($buff[$fpointer]) == 0) { 
     154                                                $fpointer++; 
     155                                                break; 
     156                                        } 
     157                                        $thisThisFileInfo['comment'] .= $buff[$fpointer]; 
     158                                        $fpointer++; 
     159                                } 
     160                        } 
     161                        // bit 1 - FLG.FHCRC 
     162                        //+---+---+ 
     163                        //| CRC16 | 
     164                        //+---+---+ 
     165                        if ($thisThisFileInfo['flags']['crc16']) { 
     166                                $w_crc = substr($buff, $fpointer, 2); 
     167                                $thisThisFileInfo['crc16'] = getid3_lib::LittleEndian2Int($w_crc); 
     168                                $fpointer += 2; 
     169                        } 
     170                        // bit 0 - FLG.FTEXT 
     171                        //if ($thisThisFileInfo['raw']['flags'] & 0x01) { 
     172                        //      Ignored... 
     173                        //} 
     174                        // bits 5, 6, 7 - reserved 
     175 
     176                        $thisThisFileInfo['crc32']    = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 8, 4)); 
     177                        $thisThisFileInfo['filesize'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 4)); 
     178 
     179                        $ThisFileInfo['gzip']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['gzip']['files'], getid3_lib::CreateDeepArray($thisThisFileInfo['filename'], '/', $thisThisFileInfo['filesize'])); 
     180 
     181                        if ($this->option_gzip_parse_contents) { 
     182                                // Try to inflate GZip 
     183                                $csize = 0; 
     184                                $inflated = ''; 
     185                                $chkcrc32 = ''; 
     186                                if (function_exists('gzinflate')) { 
     187                                        $cdata = substr($buff, $fpointer); 
     188                                        $cdata = substr($cdata, 0, strlen($cdata) - 8); 
     189                                        $csize = strlen($cdata); 
     190                                        $inflated = gzinflate($cdata); 
     191 
     192                                        // Calculate CRC32 for inflated content 
     193                                        $thisThisFileInfo['crc32_valid'] = (bool) (sprintf('%u', crc32($inflated)) == $thisThisFileInfo['crc32']); 
     194 
     195                                        // determine format 
     196                                        $formattest = substr($inflated, 0, 32774); 
     197                                        $newgetID3 = new getID3(); 
     198                                        $determined_format = $newgetID3->GetFileFormat($formattest); 
     199                                        unset($newgetID3); 
     200 
     201                                // file format is determined 
     202                                switch (@$determined_format['module']) { 
     203                                        case 'tar': 
     204                                                        // view TAR-file info 
     205                                                        if (file_exists(GETID3_INCLUDEPATH.$determined_format['include']) && @include_once(GETID3_INCLUDEPATH.$determined_format['include'])) { 
     206                                                                if (($temp_tar_filename = tempnam('*', 'getID3')) === false) { 
     207                                                                        // can't find anywhere to create a temp file, abort 
     208                                                                        $ThisFileInfo['error'][] = 'Unable to create temp file to parse TAR inside GZIP file'; 
     209                                                                        break; 
     210                                                                } 
     211                                                                if ($fp_temp_tar = fopen($temp_tar_filename, 'w+b')) { 
     212                                                                        fwrite($fp_temp_tar, $inflated); 
     213                                                                        rewind($fp_temp_tar); 
     214                                                                        $getid3_tar = new getid3_tar($fp_temp_tar, $dummy); 
     215                                                                        $ThisFileInfo['gzip']['member_header'][$idx]['tar'] = $dummy['tar']; 
     216                                                                        unset($dummy); 
     217                                                                        unset($getid3_tar); 
     218                                                                        fclose($fp_temp_tar); 
     219                                                                        unlink($temp_tar_filename); 
     220                                                                } else { 
     221                                                                        $ThisFileInfo['error'][] = 'Unable to fopen() temp file to parse TAR inside GZIP file'; 
     222                                                                        break; 
     223                                                                } 
     224                                                        } 
     225                                                        break; 
     226 
     227                                        case '': 
     228                                        default: 
     229                                                // unknown or unhandled format 
     230                                                break; 
     231                                        } 
     232                                } 
     233                        } 
     234                } 
     235                return true; 
     236        } 
     237 
     238        // Converts the OS type 
     239        function get_os_type($key) { 
     240                static $os_type = array( 
     241                        '0'   => 'FAT filesystem (MS-DOS, OS/2, NT/Win32)', 
     242                        '1'   => 'Amiga', 
     243                        '2'   => 'VMS (or OpenVMS)', 
     244                        '3'   => 'Unix', 
     245                        '4'   => 'VM/CMS', 
     246                        '5'   => 'Atari TOS', 
     247                        '6'   => 'HPFS filesystem (OS/2, NT)', 
     248                        '7'   => 'Macintosh', 
     249                        '8'   => 'Z-System', 
     250                        '9'   => 'CP/M', 
     251                        '10'  => 'TOPS-20', 
     252                        '11'  => 'NTFS filesystem (NT)', 
     253                        '12'  => 'QDOS', 
     254                        '13'  => 'Acorn RISCOS', 
     255                        '255' => 'unknown' 
     256                ); 
     257                return @$os_type[$key]; 
     258        } 
     259 
     260        // Converts the eXtra FLags 
     261        function get_xflag_type($key) { 
     262                static $xflag_type = array( 
     263                        '0' => 'unknown', 
     264                        '2' => 'maximum compression', 
     265                        '4' => 'fastest algorithm' 
     266                ); 
     267                return @$xflag_type[$key]; 
     268        } 
    294269} 
    295270 
  • extensions/charlies_content/getid3/getid3/module.archive.szip.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | module.archive.szip.php                                              | 
    18 // | module for analyzing SZIP compressed files                           | 
    19 // | dependencies: NONE                                                   | 
    20 // +----------------------------------------------------------------------+ 
    21 // 
    22 // $Id$ 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7// See readme.txt for more details                             // 
     8///////////////////////////////////////////////////////////////// 
     9//                                                             // 
     10// module.archive.szip.php                                     // 
     11// module for analyzing SZIP compressed files                  // 
     12// dependencies: NONE                                          // 
     13//                                                            /// 
     14///////////////////////////////////////////////////////////////// 
    2315 
    24          
    25          
    26 class getid3_szip extends getid3_handler 
     16 
     17class getid3_szip 
    2718{ 
    2819 
    29     public function Analyze() { 
    30          
    31         $getid3 = $this->getid3; 
     20        function getid3_szip(&$fd, &$ThisFileInfo) { 
    3221 
    33         fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET); 
    34         $szip_rkau = fread($getid3->fp, 6); 
    35          
    36         // Magic bytes:  'SZ'."\x0A\x04" 
    37              
    38         $getid3->info['fileformat']            = 'szip'; 
     22                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); 
     23                $SZIPHeader = fread($fd, 6); 
     24                if (substr($SZIPHeader, 0, 4) != 'SZ'."\x0A\x04") { 
     25                        $ThisFileInfo['error'][] = 'Expecting "SZ[x0A][x04]" at offset '.$ThisFileInfo['avdataoffset'].', found "'.substr($SZIPHeader, 0, 4).'"'; 
     26                        return false; 
     27                } 
    3928 
    40         $getid3->info['szip']['major_version'] = getid3_lib::BigEndian2Int(substr($szip_rkau, 4, 1)); 
    41         $getid3->info['szip']['minor_version'] = getid3_lib::BigEndian2Int(substr($szip_rkau, 5, 1)); 
     29                $ThisFileInfo['fileformat']            = 'szip'; 
    4230 
    43         while (!feof($getid3->fp)) { 
    44             $next_block_id = fread($getid3->fp, 2); 
    45             switch ($next_block_id) { 
    46                 case 'SZ': 
    47                     // Note that szip files can be concatenated, this has the same effect as 
    48                     // concatenating the files. this also means that global header blocks 
    49                     // might be present between directory/data blocks. 
    50                     fseek($getid3->fp, 4, SEEK_CUR); 
    51                     break; 
     31                $ThisFileInfo['szip']['major_version'] = getid3_lib::BigEndian2Int(substr($SZIPHeader, 4, 1)); 
     32                $ThisFileInfo['szip']['minor_version'] = getid3_lib::BigEndian2Int(substr($SZIPHeader, 5, 1)); 
    5233 
    53                 case 'BH': 
    54                     $bh_header_bytes  = getid3_lib::BigEndian2Int(fread($getid3->fp, 3)); 
    55                     $bh_header_data   = fread($getid3->fp, $bh_header_bytes); 
    56                     $bh_header_offset = 0; 
    57                     while (strpos($bh_header_data, "\x00", $bh_header_offset) > 0) { 
    58                         //filename as \0 terminated string  (empty string indicates end) 
    59                         //owner as \0 terminated string (empty is same as last file) 
    60                         //group as \0 terminated string (empty is same as last file) 
    61                         //3 byte filelength in this block 
    62                         //2 byte access flags 
    63                         //4 byte creation time (like in unix) 
    64                         //4 byte modification time (like in unix) 
    65                         //4 byte access time (like in unix) 
     34                while (!feof($fd)) { 
     35                        $NextBlockID = fread($fd, 2); 
     36                        switch ($NextBlockID) { 
     37                                case 'SZ': 
     38                                        // Note that szip files can be concatenated, this has the same effect as 
     39                                        // concatenating the files. this also means that global header blocks 
     40                                        // might be present between directory/data blocks. 
     41                                        fseek($fd, 4, SEEK_CUR); 
     42                                        break; 
    6643 
    67                         $bh_data_array['filename'] = substr($bh_header_data, $bh_header_offset, strcspn($bh_header_data, "\x00")); 
    68                         $bh_header_offset += (strlen($bh_data_array['filename']) + 1); 
     44                                case 'BH': 
     45                                        $BHheaderbytes  = getid3_lib::BigEndian2Int(fread($fd, 3)); 
     46                                        $BHheaderdata   = fread($fd, $BHheaderbytes); 
     47                                        $BHheaderoffset = 0; 
     48                                        while (strpos($BHheaderdata, "\x00", $BHheaderoffset) > 0) { 
     49                                                //filename as \0 terminated string  (empty string indicates end) 
     50                                                //owner as \0 terminated string (empty is same as last file) 
     51                                                //group as \0 terminated string (empty is same as last file) 
     52                                                //3 byte filelength in this block 
     53                                                //2 byte access flags 
     54                                                //4 byte creation time (like in unix) 
     55                                                //4 byte modification time (like in unix) 
     56                                                //4 byte access time (like in unix) 
    6957 
    70                         $bh_data_array['owner'] = substr($bh_header_data, $bh_header_offset, strcspn($bh_header_data, "\x00")); 
    71                         $bh_header_offset += (strlen($bh_data_array['owner']) + 1); 
     58                                                $BHdataArray['filename'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00")); 
     59                                                $BHheaderoffset += (strlen($BHdataArray['filename']) + 1); 
    7260 
    73                         $bh_data_array['group'] = substr($bh_header_data, $bh_header_offset, strcspn($bh_header_data, "\x00")); 
    74                         $bh_header_offset += (strlen($bh_data_array['group']) + 1); 
     61                                                $BHdataArray['owner'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00")); 
     62                                                $BHheaderoffset += (strlen($BHdataArray['owner']) + 1); 
    7563 
    76                         $bh_data_array['filelength'] = getid3_lib::BigEndian2Int(substr($bh_header_data, $bh_header_offset, 3)); 
    77                         $bh_header_offset += 3; 
     64                                                $BHdataArray['group'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00")); 
     65                                                $BHheaderoffset += (strlen($BHdataArray['group']) + 1); 
    7866 
    79                         $bh_data_array['access_flags'] = getid3_lib::BigEndian2Int(substr($bh_header_data, $bh_header_offset, 2)); 
    80                         $bh_header_offset += 2; 
     67                                                $BHdataArray['filelength'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 3)); 
     68                                                $BHheaderoffset += 3; 
    8169 
    82                         $bh_data_array['creation_time'] = getid3_lib::BigEndian2Int(substr($bh_header_data, $bh_header_offset, 4)); 
    83                         $bh_header_offset += 4; 
     70                                                $BHdataArray['access_flags'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 2)); 
     71                                                $BHheaderoffset += 2; 
    8472 
    85                         $bh_data_array['modification_time'] = getid3_lib::BigEndian2Int(substr($bh_header_data, $bh_header_offset, 4)); 
    86                         $bh_header_offset += 4; 
     73                                                $BHdataArray['creation_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4)); 
     74                                                $BHheaderoffset += 4; 
    8775 
    88                         $bh_data_array['access_time'] = getid3_lib::BigEndian2Int(substr($bh_header_data, $bh_header_offset, 4)); 
    89                         $bh_header_offset += 4; 
     76                                                $BHdataArray['modification_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4)); 
     77                                                $BHheaderoffset += 4; 
    9078 
    91                         $getid3->info['szip']['BH'][] = $bh_data_array; 
    92                     } 
    93                     break; 
     79                                                $BHdataArray['access_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4)); 
     80                                                $BHheaderoffset += 4; 
    9481 
    95                 default: 
    96                     break 2; 
    97             } 
    98         } 
     82                                                $ThisFileInfo['szip']['BH'][] = $BHdataArray; 
     83                                        } 
     84                                        break; 
    9985 
    100         return true; 
    101     } 
     86                                default: 
     87                                        break 2; 
     88                        } 
     89                } 
     90 
     91                return true; 
     92 
     93        } 
    10294 
    10395} 
  • extensions/charlies_content/getid3/getid3/module.archive.tar.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | module.archive.tar.php                                               | 
    18 // | module for analyzing TAR files                                       | 
    19 // | dependencies: NONE                                                   | 
    20 // +----------------------------------------------------------------------+ 
    21 // | Module originally written by Mike Mozolin <teddybearØmail*ru>        | 
    22 // +----------------------------------------------------------------------+ 
    23 // 
    24 // $Id$ 
    25  
    26          
    27          
    28 class getid3_tar extends getid3_handler 
    29 { 
    30  
    31     function Analyze() { 
    32  
    33         $info = &$this->getid3->info; 
    34  
    35         $info['fileformat'] = 'tar'; 
    36  
    37         $fp = $this->getid3->fp; 
    38          
    39         fseek($fp, 0); 
    40          
    41         $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix'; 
    42  
    43         $null_512k = str_repeat("\0", 512); // end-of-file marker 
    44  
    45         $already_warned = false; 
    46  
    47         while (!feof($fp)) { 
    48              
    49             $buffer = fread($fp, 512); 
    50              
    51             // check the block 
    52             $checksum = 0; 
    53             for ($i = 0; $i < 148; $i++) { 
    54                 $checksum += ord(substr($buffer, $i, 1)); 
    55             } 
    56             for ($i = 148; $i < 156; $i++) { 
    57                 $checksum += ord(' '); 
    58             } 
    59             for ($i = 156; $i < 512; $i++) { 
    60                 $checksum += ord(substr($buffer, $i, 1)); 
    61             } 
    62             $attr    = unpack($unpack_header, $buffer); 
    63             $name    =        trim(@$attr['fname']); 
    64             $mode    = octdec(trim(@$attr['mode'])); 
    65             $uid     = octdec(trim(@$attr['uid'])); 
    66             $gid     = octdec(trim(@$attr['gid'])); 
    67             $size    = octdec(trim(@$attr['size'])); 
    68             $mtime   = octdec(trim(@$attr['mtime'])); 
    69             $chksum  = octdec(trim(@$attr['chksum'])); 
    70             $typflag =        trim(@$attr['typflag']); 
    71             $lnkname =        trim(@$attr['lnkname']); 
    72             $magic   =        trim(@$attr['magic']); 
    73             $ver     =        trim(@$attr['ver']); 
    74             $uname   =        trim(@$attr['uname']); 
    75             $gname   =        trim(@$attr['gname']); 
    76             $devmaj  = octdec(trim(@$attr['devmaj'])); 
    77             $devmin  = octdec(trim(@$attr['devmin'])); 
    78             $prefix  =        trim(@$attr['prefix']); 
    79  
    80             // EOF Found 
    81             if (($checksum == 256) && ($chksum == 0)) { 
    82                 break; 
    83             } 
    84  
    85             // Check if filename if 7bit as spec requires 
    86             if (!$already_warned) { 
    87                 for ($i = 0; $i < strlen($name); $i++) { 
    88                     if ($name{$i} < chr(32) || $name{$i} > chr(127)) { 
    89                         $this->getid3->warning('Some filenames contains extended characters, which breaks the tar specifation. This is not uncommon, but you will have to handle the character encoding for filenames yourself.'); 
    90                         $already_warned = true; 
    91                         break; 
    92                     } 
    93                 } 
    94             } 
    95              
    96             if ($prefix) { 
    97                 $name = $prefix.'/'.$name; 
    98             } 
    99             if ((preg_match('#/$#', $name)) && !$name) { 
    100                 $typeflag = 5; 
    101             } 
    102              
    103             // If it's the end of the tar-file... 
    104             if ($buffer == $null_512k) { 
    105                 break; 
    106             } 
    107              
    108             // Protect against tar-files with garbage at the end 
    109             if ($name == '') { 
    110                 break; 
    111             } 
    112              
    113             $info['tar']['file_details'][$name] = array ( 
    114                 'name'     => $name, 
    115                 'mode_raw' => $mode, 
    116                 'mode'     => getid3_tar::display_perms($mode), 
    117                 'uid'      => $uid, 
    118                 'gid'      => $gid, 
    119                 'size'     => $size, 
    120                 'mtime'    => $mtime, 
    121                 'chksum'   => $chksum, 
    122                 'typeflag' => getid3_tar::get_flag_type($typflag), 
    123                 'linkname' => $lnkname, 
    124                 'magic'    => $magic, 
    125                 'version'  => $ver, 
    126                 'uname'    => $uname, 
    127                 'gname'    => $gname, 
    128                 'devmajor' => $devmaj, 
    129                 'devminor' => $devmin 
    130             ); 
    131              
    132             // Skip the next chunk 
    133             fseek($fp, $size, SEEK_CUR); 
    134  
    135             // Throw away padding 
    136             if ($size % 512) { 
    137                 fseek($fp, 512 - $diff, SEEK_CUR); 
    138             } 
    139              
    140         } 
    141         return true; 
    142     } 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7// See readme.txt for more details                             // 
     8///////////////////////////////////////////////////////////////// 
     9//                                                             // 
     10// module.archive.tar.php                                      // 
     11// module for analyzing TAR files                              // 
     12// dependencies: NONE                                          // 
     13//                                                            /// 
     14///////////////////////////////////////////////////////////////// 
     15//                                                             // 
     16// Module originally written by                                // 
     17//      Mike Mozolin <teddybearØmail*ru>                       // 
     18//                                                             // 
     19///////////////////////////////////////////////////////////////// 
    14320 
    14421 
    145     // Parses the file mode to file permissions 
    146     public static function display_perms($mode) { 
     22class getid3_tar { 
    14723 
    148         // Determine Type 
    149         if ($mode & 0x1000) { 
    150             $type='p'; // FIFO pipe 
    151         } 
    152         elseif ($mode & 0x2000) { 
    153             $type='c'; // Character special 
    154         } 
    155         elseif ($mode & 0x4000) { 
    156             $type='d'; // Directory 
    157         } 
    158         elseif ($mode & 0x6000) { 
    159             $type='b'; // Block special 
    160         } 
    161         elseif ($mode & 0x8000) { 
    162             $type='-'; // Regular 
    163         } 
    164         elseif ($mode & 0xA000) { 
    165             $type='l'; // Symbolic Link 
    166         } 
    167         elseif ($mode & 0xC000) { 
    168             $type='s'; // Socket 
    169         } 
    170         else { 
    171             $type='u'; // UNKNOWN 
    172         } 
     24        function getid3_tar(&$fd, &$ThisFileInfo) { 
     25                $ThisFileInfo['fileformat'] = 'tar'; 
     26                $ThisFileInfo['tar']['files'] = array(); 
    17327 
    174         // Determine permissions 
    175         $owner['read']    = (($mode & 00400) ? 'r' : '-'); 
    176         $owner['write']   = (($mode & 00200) ? 'w' : '-'); 
    177         $owner['execute'] = (($mode & 00100) ? 'x' : '-'); 
    178         $group['read']    = (($mode & 00040) ? 'r' : '-'); 
    179         $group['write']   = (($mode & 00020) ? 'w' : '-'); 
    180         $group['execute'] = (($mode & 00010) ? 'x' : '-'); 
    181         $world['read']    = (($mode & 00004) ? 'r' : '-'); 
    182         $world['write']   = (($mode & 00002) ? 'w' : '-'); 
    183         $world['execute'] = (($mode & 00001) ? 'x' : '-'); 
     28                $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155prefix'; 
     29                $null_512k = str_repeat("\x00", 512); // end-of-file marker 
    18430 
    185         // Adjust for SUID, SGID and sticky bit 
    186         if ($mode & 0x800) { 
    187             $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S'; 
    188         } 
    189         if ($mode & 0x400) { 
    190             $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S'; 
    191         } 
    192         if ($mode & 0x200) { 
    193             $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T'; 
    194         } 
     31                @fseek($fd, 0); 
     32                while (!feof($fd)) { 
     33                        $buffer = fread($fd, 512); 
     34                        if (strlen($buffer) < 512) { 
     35                                break; 
     36                        } 
    19537 
    196         $s  = sprintf('%1s', $type); 
    197         $s .= sprintf('%1s%1s%1s',      $owner['read'], $owner['write'], $owner['execute']); 
    198         $s .= sprintf('%1s%1s%1s',      $group['read'], $group['write'], $group['execute']); 
    199         $s .= sprintf('%1s%1s%1s'."\n", $world['read'], $world['write'], $world['execute']); 
     38                        // check the block 
     39                        $checksum = 0; 
     40                        for ($i = 0; $i < 148; $i++) { 
     41                                $checksum += ord($buffer{$i}); 
     42                        } 
     43                        for ($i = 148; $i < 156; $i++) { 
     44                                $checksum += ord(' '); 
     45                        } 
     46                        for ($i = 156; $i < 512; $i++) { 
     47                                $checksum += ord($buffer{$i}); 
     48                        } 
     49                        $attr    = unpack($unpack_header, $buffer); 
     50                        $name    =        trim(@$attr['fname']); 
     51                        $mode    = octdec(trim(@$attr['mode'])); 
     52                        $uid     = octdec(trim(@$attr['uid'])); 
     53                        $gid     = octdec(trim(@$attr['gid'])); 
     54                        $size    = octdec(trim(@$attr['size'])); 
     55                        $mtime   = octdec(trim(@$attr['mtime'])); 
     56                        $chksum  = octdec(trim(@$attr['chksum'])); 
     57                        $typflag =        trim(@$attr['typflag']); 
     58                        $lnkname =        trim(@$attr['lnkname']); 
     59                        $magic   =        trim(@$attr['magic']); 
     60                        $ver     =        trim(@$attr['ver']); 
     61                        $uname   =        trim(@$attr['uname']); 
     62                        $gname   =        trim(@$attr['gname']); 
     63                        $devmaj  = octdec(trim(@$attr['devmaj'])); 
     64                        $devmin  = octdec(trim(@$attr['devmin'])); 
     65                        $prefix  =        trim(@$attr['prefix']); 
     66                        if (($checksum == 256) && ($chksum == 0)) { 
     67                                // EOF Found 
     68                                break; 
     69                        } 
     70                        if ($prefix) { 
     71                                $name = $prefix.'/'.$name; 
     72                        } 
     73                        if ((preg_match('#/$#', $name)) && !$name) { 
     74                                $typeflag = 5; 
     75                        } 
     76                        if ($buffer == $null_512k) { 
     77                                // it's the end of the tar-file... 
     78                                break; 
     79                        } 
    20080 
    201         return $s; 
    202     } 
     81                        // Read to the next chunk 
     82                        fseek($fd, $size, SEEK_CUR); 
    20383 
     84                        $diff = $size % 512; 
     85                        if ($diff != 0) { 
     86                                // Padding, throw away 
     87                                fseek($fd, (512 - $diff), SEEK_CUR); 
     88                        } 
     89                        // Protect against tar-files with garbage at the end 
     90                        if ($name == '') { 
     91                                break; 
     92                        } 
     93                        $ThisFileInfo['tar']['file_details'][$name] = array ( 
     94                                'name'     => $name, 
     95                                'mode_raw' => $mode, 
     96                                'mode'     => getid3_tar::display_perms($mode), 
     97                                'uid'      => $uid, 
     98                                'gid'      => $gid, 
     99                                'size'     => $size, 
     100                                'mtime'    => $mtime, 
     101                                'chksum'   => $chksum, 
     102                                'typeflag' => getid3_tar::get_flag_type($typflag), 
     103                                'linkname' => $lnkname, 
     104                                'magic'    => $magic, 
     105                                'version'  => $ver, 
     106                                'uname'    => $uname, 
     107                                'gname'    => $gname, 
     108                                'devmajor' => $devmaj, 
     109                                'devminor' => $devmin 
     110                        ); 
     111                        $ThisFileInfo['tar']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['tar']['files'], getid3_lib::CreateDeepArray($ThisFileInfo['tar']['file_details'][$name]['name'], '/', $size)); 
     112                } 
     113                return true; 
     114        } 
    204115 
    205     // Converts the file type 
    206     public static function get_flag_type($typflag) { 
     116        // Parses the file mode to file permissions 
     117        function display_perms($mode) { 
     118                // Determine Type 
     119                if     ($mode & 0x1000) $type='p'; // FIFO pipe 
     120                elseif ($mode & 0x2000) $type='c'; // Character special 
     121                elseif ($mode & 0x4000) $type='d'; // Directory 
     122                elseif ($mode & 0x6000) $type='b'; // Block special 
     123                elseif ($mode & 0x8000) $type='-'; // Regular 
     124                elseif ($mode & 0xA000) $type='l'; // Symbolic Link 
     125                elseif ($mode & 0xC000) $type='s'; // Socket 
     126                else                    $type='u'; // UNKNOWN 
    207127 
    208         static $flag_types = array ( 
    209             '0' => 'LF_NORMAL', 
    210             '1' => 'LF_LINK', 
    211             '2' => 'LF_SYNLINK', 
    212             '3' => 'LF_CHR', 
    213             '4' => 'LF_BLK', 
    214             '5' => 'LF_DIR', 
    215             '6' => 'LF_FIFO', 
    216             '7' => 'LF_CONFIG', 
    217             'D' => 'LF_DUMPDIR', 
    218             'K' => 'LF_LONGLINK', 
    219             'L' => 'LF_LONGNAME', 
    220             'M' => 'LF_MULTIVOL', 
    221             'N' => 'LF_NAMES', 
    222             'S' => 'LF_SPARSE', 
    223             'V' => 'LF_VOLHDR' 
    224         ); 
     128                // Determine permissions 
     129                $owner['read']    = (($mode & 00400) ? 'r' : '-'); 
     130                $owner['write']   = (($mode & 00200) ? 'w' : '-'); 
     131                $owner['execute'] = (($mode & 00100) ? 'x' : '-'); 
     132                $group['read']    = (($mode & 00040) ? 'r' : '-'); 
     133                $group['write']   = (($mode & 00020) ? 'w' : '-'); 
     134                $group['execute'] = (($mode & 00010) ? 'x' : '-'); 
     135                $world['read']    = (($mode & 00004) ? 'r' : '-'); 
     136                $world['write']   = (($mode & 00002) ? 'w' : '-'); 
     137                $world['execute'] = (($mode & 00001) ? 'x' : '-'); 
    225138 
    226         return @$flag_types[$typflag]; 
    227     } 
    228      
     139                // Adjust for SUID, SGID and sticky bit 
     140                if ($mode & 0x800) $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S'; 
     141                if ($mode & 0x400) $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S'; 
     142                if ($mode & 0x200) $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T'; 
     143 
     144                $s  = sprintf('%1s', $type); 
     145                $s .= sprintf('%1s%1s%1s',      $owner['read'], $owner['write'], $owner['execute']); 
     146                $s .= sprintf('%1s%1s%1s',      $group['read'], $group['write'], $group['execute']); 
     147                $s .= sprintf('%1s%1s%1s'."\n", $world['read'], $world['write'], $world['execute']); 
     148                return $s; 
     149        } 
     150 
     151        // Converts the file type 
     152        function get_flag_type($typflag) { 
     153                static $flag_types = array( 
     154                        '0' => 'LF_NORMAL', 
     155                        '1' => 'LF_LINK', 
     156                        '2' => 'LF_SYNLINK', 
     157                        '3' => 'LF_CHR', 
     158                        '4' => 'LF_BLK', 
     159                        '5' => 'LF_DIR', 
     160                        '6' => 'LF_FIFO', 
     161                        '7' => 'LF_CONFIG', 
     162                        'D' => 'LF_DUMPDIR', 
     163                        'K' => 'LF_LONGLINK', 
     164                        'L' => 'LF_LONGNAME', 
     165                        'M' => 'LF_MULTIVOL', 
     166                        'N' => 'LF_NAMES', 
     167                        'S' => 'LF_SPARSE', 
     168                        'V' => 'LF_VOLHDR' 
     169                ); 
     170                return @$flag_types[$typflag]; 
     171        } 
     172 
    229173} 
    230174 
  • extensions/charlies_content/getid3/getid3/module.archive.zip.php

    r3318 r3544  
    11<?php 
    2 // +----------------------------------------------------------------------+ 
    3 // | PHP version 5                                                        | 
    4 // +----------------------------------------------------------------------+ 
    5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 | 
    6 // +----------------------------------------------------------------------+ 
    7 // | This source file is subject to version 2 of the GPL license,         | 
    8 // | that is bundled with this package in the file license.txt and is     | 
    9 // | available through the world-wide-web at the following url:           | 
    10 // | http://www.gnu.org/copyleft/gpl.html                                 | 
    11 // +----------------------------------------------------------------------+ 
    12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    | 
    13 // +----------------------------------------------------------------------+ 
    14 // | Authors: James Heinrich <infoØgetid3*org>                            | 
    15 // |          Allan Hansen <ahØartemis*dk>                                | 
    16 // +----------------------------------------------------------------------+ 
    17 // | module.archive.zip.php                                               | 
    18 // | Module for analyzing pkZip files                                     | 
    19 // | dependencies: NONE                                                   | 
    20 // +----------------------------------------------------------------------+ 
    21 // 
    22 // $Id$ 
    23  
    24  
    25  
    26 class getid3_zip extends getid3_handler 
     2///////////////////////////////////////////////////////////////// 
     3/// getID3() by James Heinrich <info@getid3.org>               // 
     4//  available at http://getid3.sourceforge.net                 // 
     5//            or http://www.getid3.org                         // 
     6///////////////////////////////////////////////////////////////// 
     7// See readme.txt for more details                             // 
     8///////////////////////////////////////////////////////////////// 
     9//                                                             // 
     10// module.archive.zip.php                                      // 
     11// module for analyzing pkZip files                            // 
     12// dependencies: NONE                                          // 
     13//                                                            /// 
     14///////////////////////////////////////////////////////////////// 
     15 
     16 
     17class getid3_zip 
    2718{ 
    2819 
    29     public function Analyze() {