eZ Publish  [trunk]
ezgifimageanalyzer.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZGIFImageAnalyzer class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012   \class eZGIFImageAnalyzer ezgifimageanalyzer.php
00013   \ingroup eZImageAnalyzer
00014   \brief The class eZGIFImageAnalyzer does
00015 
00016 */
00017 
00018 class eZGIFImageAnalyzer
00019 {
00020     /*!
00021      Constructor
00022     */
00023     function eZGIFImageAnalyzer()
00024     {
00025     }
00026 
00027     /*!
00028      Checks the file for GIF data blocks and returns information on the GIF file.
00029     */
00030     function process( $mimeData, $parameters = array() )
00031     {
00032         $printInfo = false;
00033         if ( isset( $parameters['print_info'] ) )
00034             $printInfo = $parameters['print_info'];
00035 
00036         $filename = $mimeData['url'];
00037         $fd = fopen( $filename, 'rb' );
00038         if ( $fd )
00039         {
00040             $blockTypes = array( 0x21 => 'Exension Introducer',
00041                                  0x2c => 'Image Descriptor',
00042                                  0x3b => 'Trailer' );
00043             $extensionLabels = array( 0xf9 => 'Graphical Control Extension',
00044                                       0xff => 'Application Extension',
00045                                       0xfe => 'Comment Extension' );
00046             // Read GIF header
00047             $data = fread( $fd, 6 );
00048             if ( $data == 'GIF87a' or
00049                  $data == 'GIF89a' )
00050             {
00051                 $info = array();
00052 
00053                 $info['version'] = substr( $data, 3 );
00054                 $info['frame_count'] = 0;
00055                 $info['mode'] = eZImageAnalyzer::MODE_INDEXED;
00056                 $offset = 6;
00057 
00058                 $info['animation_timer'] = false;
00059                 $info['animation_timer_type'] = eZImageAnalyzer::TIMER_HUNDRETHS_OF_A_SECOND;
00060 
00061                 $info['comment_list'] = array();
00062 
00063                 $info['transparency_type'] = eZImageAnalyzer::TRANSPARENCY_OPAQUE;
00064 
00065                 // Read Logical Screen Descriptor
00066                 $data = fread( $fd, 7 );
00067                 $offset += 7;
00068 
00069                 $lsdFields = ord( $data[4] );
00070 
00071                 $globalColorCount = 0;
00072                 $globalColorTableSize = 0;
00073                 if ( $lsdFields >> 7 )
00074                 {
00075                     $globalColorCount = ( 1 << ( ( $lsdFields & 0x07 ) + 1) );
00076                     $globalColorTableSize = $globalColorCount * 3;
00077                 }
00078 
00079                 $info['color_count'] = $globalColorCount;
00080 
00081                 $info['width'] = ( ord( $data[1] ) << 8 ) + ord( $data[0] );
00082                 $info['height'] = ( ord( $data[3] ) << 8 ) + ord( $data[2] );
00083 
00084 
00085                 if ( $globalColorTableSize )
00086                 {
00087                     fseek( $fd, $globalColorTableSize, SEEK_CUR );
00088                     $offset += $globalColorTableSize;
00089                 }
00090                 if ( $printInfo )
00091                     print( "Global color table size=$globalColorTableSize\n" );
00092 
00093                 $done = false;
00094                 while ( !$done )
00095                 {
00096                     $data = fread( $fd, 1 );
00097                     $offset += 1;
00098                     $blockType = ord( $data[0] );
00099                     if ( $printInfo )
00100                     {
00101                         print( "Block type=0x" . dechex( $blockType ) );
00102                         if ( isset( $blockTypes[$blockType] ) )
00103                             print( " (" . $blockTypes[$blockType] . ")" );
00104                         print( "\n" );
00105                     }
00106                     if ( $blockType == 0x21 ) // Extension Introducer
00107                     {
00108                         $data .= fread( $fd, 1 );
00109                         $offset += 1;
00110                         $extensionLabel = ord( $data[1] );
00111                         if ( $printInfo )
00112                         {
00113                             print( "> " . "Extension label=0x" . dechex( $extensionLabel ) );
00114                             if ( isset( $extensionLabels[$extensionLabel] ) )
00115                                 print( " (" . $extensionLabels[$extensionLabel] . ")" );
00116                             print( "\n" );
00117                         }
00118                         if ( $extensionLabel == 0xf9 ) // Graphical Control Extension
00119                         {
00120                             $data = fread( $fd, 5 + 1 );
00121                             $info['animation_timer'] = ( ord( $data[3] ) << 8 ) + ord( $data[2] );
00122                             $gceFlags = ord( $data[1] );
00123                             if ( $gceFlags & 0x01 )
00124                                 $info['transparency_type'] = eZImageAnalyzer::TRANSPARENCY_TRANSPARENT;
00125                             $offset += 5 + 1;
00126                         }
00127                         else if ( $extensionLabel == 0xff ) // Application Extension
00128                         {
00129                             $data = fread( $fd, 12 );
00130                             if ( $printInfo )
00131                             {
00132                                 $applicationIdentifier = substr( $data, 1, 8 );
00133                                 $applicationAuthentication = substr( $data, 1 + 8, 3 );
00134                                 print( ">> Application identifier: $applicationIdentifier\n" );
00135                                 print( ">> Application authentication: $applicationAuthentication\n" );
00136                             }
00137                             $offset += 12;
00138 
00139                             $dataBlockDone = false;
00140                             while ( !$dataBlockDone )
00141                             {
00142                                 $data = fread( $fd, 1 );
00143                                 $offset += 1;
00144                                 $blockBytes = ord( $data[0] );
00145                                 if ( $printInfo )
00146                                     print( ">> Application Block size=$blockBytes\n" );
00147                                 if ( $blockBytes )
00148                                 {
00149                                     fseek( $fd, $blockBytes, SEEK_CUR );
00150                                     $offset += $blockBytes;
00151                                 }
00152                                 else
00153                                 {
00154                                     if ( $printInfo )
00155                                         print( ">> GIF application blocks terminated by 0 image block\n" );
00156                                     $dataBlockDone = true;
00157                                 }
00158                             }
00159                         }
00160                         else if ( $extensionLabel == 0xfe ) // Comment Extension
00161                         {
00162                             $commentBlockDone = false;
00163                             $comment = false;
00164                             while ( !$commentBlockDone )
00165                             {
00166                                 $data = fread( $fd, 1 );
00167                                 $offset += 1;
00168                                 $blockBytes = ord( $data[0] );
00169                                 if ( $printInfo )
00170                                     print( ">> Comment Block size=$blockBytes\n" );
00171                                 if ( $blockBytes )
00172                                 {
00173                                     $data = fread( $fd, $blockBytes );
00174                                     if ( $printInfo )
00175                                         print( $data );
00176                                     $comment .= $data;
00177                                     $offset += $blockBytes;
00178                                 }
00179                                 else
00180                                 {
00181                                     if ( $printInfo )
00182                                         print( ">> GIF comment blocks terminated by 0 image block\n" );
00183                                     $commentBlockDone = true;
00184                                 }
00185                             }
00186                             if ( $comment )
00187                                 $info['comment_list'][] = $comment;
00188                         }
00189                         else
00190                         {
00191                             if ( $printInfo )
00192                                 print( "> Unknown extension label, aborting\n" );
00193                             $done = true;
00194                         }
00195                     }
00196                     else if ( $blockType == 0x2c ) // Image Descriptor
00197                     {
00198                         $info['frame_count'] += 1;
00199                         $data .= fread( $fd, 9 );
00200                         $localColorTableSize = 0;
00201                         $localColorCount = 0;
00202                         $idFields = ord( $data[9] );
00203                         if ( $idFields >> 7 ) // Local Color Table
00204                         {
00205                             $localColorCount = ( 1 << ( ( $idFields & 0x07 ) + 1) );
00206                             $localColorTableSize = $localColorCount * 3;
00207                         }
00208                         if ( $localColorCount > $globalColorCount )
00209                             $info['color_count'] = $localColorCount;
00210 
00211                         if ( $localColorTableSize )
00212                         {
00213                             fseek( $fd, $localColorTableSize, SEEK_CUR );
00214                             $offset += $localColorTableSize;
00215                         }
00216                         if ( $printInfo )
00217                             print( ">> Local color table size=$localColorTableSize\n" );
00218 
00219                         $lzwCodeSize = fread( $fd, 1 ); // LZW Minimum Code Size
00220                         $offset += 1;
00221 
00222                         $dataBlockDone = false;
00223                         while ( !$dataBlockDone )
00224                         {
00225                             $data = fread( $fd, 1 );
00226                             $offset += 1;
00227                             $blockBytes = ord( $data[0] );
00228                             if ( $printInfo )
00229                                 print( ">> Block size=$blockBytes\n" );
00230                             if ( $blockBytes )
00231                             {
00232                                 fseek( $fd, $blockBytes, SEEK_CUR );
00233                                 $offset += $blockBytes;
00234                             }
00235                             else
00236                             {
00237                                 if ( $printInfo )
00238                                     print( ">> GIF image blocks terminated by 0 image block\n" );
00239                                 $dataBlockDone = true;
00240                             }
00241                         }
00242                     }
00243                     else if ( $blockType == 0x3b ) // Trailer, end of stream
00244                     {
00245                         if ( $printInfo )
00246                             print( "GIF stream terminated by Trailer block\n" );
00247                         $done = true;
00248                     }
00249                     if ( feof( $fd ) )
00250                         $done = true;
00251                 }
00252             }
00253             else
00254             {
00255                 if ( $printInfo )
00256                     print( "Not GIF\n" );
00257                 eZDebug::writeError( "The image file $filename is not a GIF file, cannot analyze it", __METHOD__ );
00258             }
00259             fclose( $fd );
00260             $info['is_animated'] = $info['frame_count'] > 1;
00261             return $info;
00262         }
00263         return false;
00264     }
00265 
00266 }
00267 
00268 ?>