eZ Publish  [4.0]
ezgifimageanalyzer.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZGIFImageAnalyzer class
00004 //
00005 // Created on: <03-Nov-2003 15:19:16 amos>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezgifimageanalyzer.php
00032 */
00033 
00034 /*!
00035   \class eZGIFImageAnalyzer ezgifimageanalyzer.php
00036   \ingroup eZImageAnalyzer
00037   \brief The class eZGIFImageAnalyzer does
00038 
00039 */
00040 
00041 class eZGIFImageAnalyzer
00042 {
00043     /*!
00044      Constructor
00045     */
00046     function eZGIFImageAnalyzer()
00047     {
00048     }
00049 
00050     /*!
00051      \reimp
00052      Checks the file for GIF data blocks and returns information on the GIF file.
00053     */
00054     function process( $mimeData, $parameters = array() )
00055     {
00056         $printInfo = false;
00057         if ( isset( $parameters['print_info'] ) )
00058             $printInfo = $parameters['print_info'];
00059 
00060         $filename = $mimeData['url'];
00061         $fd = fopen( $filename, 'rb' );
00062         if ( $fd )
00063         {
00064             $blockTypes = array( 0x21 => 'Exension Introducer',
00065                                  0x2c => 'Image Descriptor',
00066                                  0x3b => 'Trailer' );
00067             $extensionLabels = array( 0xf9 => 'Graphical Control Extension',
00068                                       0xff => 'Application Extension',
00069                                       0xfe => 'Comment Extension' );
00070             // Read GIF header
00071             $data = fread( $fd, 6 );
00072             if ( $data == 'GIF87a' or
00073                  $data == 'GIF89a' )
00074             {
00075                 $info = array();
00076 
00077                 $info['version'] = substr( $data, 3 );
00078                 $info['frame_count'] = 0;
00079                 $info['mode'] = eZImageAnalyzer::MODE_INDEXED;
00080                 $offset = 6;
00081 
00082                 $info['animation_timer'] = false;
00083                 $info['animation_timer_type'] = eZImageAnalyzer::TIMER_HUNDRETHS_OF_A_SECOND;
00084 
00085                 $info['comment_list'] = array();
00086 
00087                 $info['transparency_type'] = eZImageAnalyzer::TRANSPARENCY_OPAQUE;
00088 
00089                 // Read Logical Screen Descriptor
00090                 $data = fread( $fd, 7 );
00091                 $offset += 7;
00092 
00093                 $lsdFields = ord( $data[4] );
00094 
00095                 $globalColorCount = 0;
00096                 $globalColorTableSize = 0;
00097                 if ( $lsdFields >> 7 )
00098                 {
00099                     $globalColorCount = ( 1 << ( ( $lsdFields & 0x07 ) + 1) );
00100                     $globalColorTableSize = $globalColorCount * 3;
00101                 }
00102 
00103                 $info['color_count'] = $globalColorCount;
00104 
00105                 $info['width'] = ( ord( $data[1] ) << 8 ) + ord( $data[0] );
00106                 $info['height'] = ( ord( $data[3] ) << 8 ) + ord( $data[2] );
00107 
00108 
00109                 if ( $globalColorTableSize )
00110                 {
00111                     fseek( $fd, $globalColorTableSize, SEEK_CUR );
00112                     $offset += $globalColorTableSize;
00113                 }
00114                 if ( $printInfo )
00115                     print( "Global color table size=$globalColorTableSize\n" );
00116 
00117                 $done = false;
00118                 while ( !$done )
00119                 {
00120                     $data = fread( $fd, 1 );
00121                     $offset += 1;
00122                     $blockType = ord( $data[0] );
00123                     if ( $printInfo )
00124                     {
00125                         print( "Block type=0x" . dechex( $blockType ) );
00126                         if ( isset( $blockTypes[$blockType] ) )
00127                             print( " (" . $blockTypes[$blockType] . ")" );
00128                         print( "\n" );
00129                     }
00130                     if ( $blockType == 0x21 ) // Extension Introducer
00131                     {
00132                         $data .= fread( $fd, 1 );
00133                         $offset += 1;
00134                         $extensionLabel = ord( $data[1] );
00135                         if ( $printInfo )
00136                         {
00137                             print( "> " . "Extension label=0x" . dechex( $extensionLabel ) );
00138                             if ( isset( $extensionLabels[$extensionLabel] ) )
00139                                 print( " (" . $extensionLabels[$extensionLabel] . ")" );
00140                             print( "\n" );
00141                         }
00142                         if ( $extensionLabel == 0xf9 ) // Graphical Control Extension
00143                         {
00144                             $data = fread( $fd, 5 + 1 );
00145                             $info['animation_timer'] = ( ord( $data[3] ) << 8 ) + ord( $data[2] );
00146                             $gceFlags = ord( $data[1] );
00147                             if ( $gceFlags & 0x01 )
00148                                 $info['transparency_type'] = eZImageAnalyzer::TRANSPARENCY_TRANSPARENT;
00149                             $offset += 5 + 1;
00150                         }
00151                         else if ( $extensionLabel == 0xff ) // Application Extension
00152                         {
00153                             $data = fread( $fd, 12 );
00154                             if ( $printInfo )
00155                             {
00156                                 $applicationIdentifier = substr( $data, 1, 8 );
00157                                 $applicationAuthentication = substr( $data, 1 + 8, 3 );
00158                                 print( ">> Application identifier: $applicationIdentifier\n" );
00159                                 print( ">> Application authentication: $applicationAuthentication\n" );
00160                             }
00161                             $offset += 12;
00162 
00163                             $dataBlockDone = false;
00164                             while ( !$dataBlockDone )
00165                             {
00166                                 $data = fread( $fd, 1 );
00167                                 $offset += 1;
00168                                 $blockBytes = ord( $data[0] );
00169                                 if ( $printInfo )
00170                                     print( ">> Application Block size=$blockBytes\n" );
00171                                 if ( $blockBytes )
00172                                 {
00173                                     fseek( $fd, $blockBytes, SEEK_CUR );
00174                                     $offset += $blockBytes;
00175                                 }
00176                                 else
00177                                 {
00178                                     if ( $printInfo )
00179                                         print( ">> GIF application blocks terminated by 0 image block\n" );
00180                                     $dataBlockDone = true;
00181                                 }
00182                             }
00183                         }
00184                         else if ( $extensionLabel == 0xfe ) // Comment Extension
00185                         {
00186                             $commentBlockDone = false;
00187                             $comment = false;
00188                             while ( !$commentBlockDone )
00189                             {
00190                                 $data = fread( $fd, 1 );
00191                                 $offset += 1;
00192                                 $blockBytes = ord( $data[0] );
00193                                 if ( $printInfo )
00194                                     print( ">> Comment Block size=$blockBytes\n" );
00195                                 if ( $blockBytes )
00196                                 {
00197                                     $data = fread( $fd, $blockBytes );
00198                                     if ( $printInfo )
00199                                         print( $data );
00200                                     $comment .= $data;
00201                                     $offset += $blockBytes;
00202                                 }
00203                                 else
00204                                 {
00205                                     if ( $printInfo )
00206                                         print( ">> GIF comment blocks terminated by 0 image block\n" );
00207                                     $commentBlockDone = true;
00208                                 }
00209                             }
00210                             if ( $comment )
00211                                 $info['comment_list'][] = $comment;
00212                         }
00213                         else
00214                         {
00215                             if ( $printInfo )
00216                                 print( "> Unknown extension label, aborting\n" );
00217                             $done = true;
00218                         }
00219                     }
00220                     else if ( $blockType == 0x2c ) // Image Descriptor
00221                     {
00222                         $info['frame_count'] += 1;
00223                         $data .= fread( $fd, 9 );
00224                         $localColorTableSize = 0;
00225                         $localColorCount = 0;
00226                         $idFields = ord( $data[9] );
00227                         if ( $idFields >> 7 ) // Local Color Table
00228                         {
00229                             $localColorCount = ( 1 << ( ( $idFields & 0x07 ) + 1) );
00230                             $localColorTableSize = $localColorCount * 3;
00231                         }
00232                         if ( $localColorCount > $globalColorCount )
00233                             $info['color_count'] = $localColorCount;
00234 
00235                         if ( $localColorTableSize )
00236                         {
00237                             fseek( $fd, $localColorTableSize, SEEK_CUR );
00238                             $offset += $localColorTableSize;
00239                         }
00240                         if ( $printInfo )
00241                             print( ">> Local color table size=$localColorTableSize\n" );
00242 
00243                         $lzwCodeSize = fread( $fd, 1 ); // LZW Minimum Code Size
00244                         $offset += 1;
00245 
00246                         $dataBlockDone = false;
00247                         while ( !$dataBlockDone )
00248                         {
00249                             $data = fread( $fd, 1 );
00250                             $offset += 1;
00251                             $blockBytes = ord( $data[0] );
00252                             if ( $printInfo )
00253                                 print( ">> Block size=$blockBytes\n" );
00254                             if ( $blockBytes )
00255                             {
00256                                 fseek( $fd, $blockBytes, SEEK_CUR );
00257                                 $offset += $blockBytes;
00258                             }
00259                             else
00260                             {
00261                                 if ( $printInfo )
00262                                     print( ">> GIF image blocks terminated by 0 image block\n" );
00263                                 $dataBlockDone = true;
00264                             }
00265                         }
00266                     }
00267                     else if ( $blockType == 0x3b ) // Trailer, end of stream
00268                     {
00269                         if ( $printInfo )
00270                             print( "GIF stream terminated by Trailer block\n" );
00271                         $done = true;
00272                     }
00273                     if ( feof( $fd ) )
00274                         $done = true;
00275                 }
00276             }
00277             else
00278             {
00279                 if ( $printInfo )
00280                     print( "Not GIF\n" );
00281                 eZDebug::writeError( "The image file $filename is not a GIF file, cannot analyze it",
00282                                      'eZGIFImageAnalyzer::process' );
00283             }
00284             fclose( $fd );
00285             $info['is_animated'] = $info['frame_count'] > 1;
00286             return $info;
00287         }
00288         return false;
00289     }
00290 
00291 }
00292 
00293 ?>