|
eZ Publish
[trunk]
|
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 ?>