Apache Zeta Components Manual :: File Source for php.php
Source for file php.php
Documentation is available at php.php
* File containing the ezcImageAnalyzerPhpHandler class.
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* @version //autogentag//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* Class to retrieve information about a given image file.
* This handler implements image analyzation using direct PHP functionality,
* mainly the {@link getimagesize()} function and, if available, the EXIF
* extension {@link exif_read_data()}. The driver is capable of determining
* the type the following file formats:
* The driver determines the MIME type of these images (using the
* {@link ezcImageAnalyzerPhpHandler::analyzeType()} method). The width,
* height and size of the given image are always available after analyzing a
* file, if the file in general can be analyzed
* {@link ezcImageAnalyzerPhpHandler::canAnalyze()}.
* For JPEG and TIFF images this driver will try to read in information using
* the EXIF extension in PHP and fills in the following properties of the
* {@link ezcImageAnalyzerData} struct, returned by the
* {@link ezcImageAnalyzerPhpHandler::analyzeImage()} method:
* For GIF (also animated) it finds information by scanning the file manually
* and fills in the following properties of the
* {@link ezcImageAnalyzerData} struct, returned by the
* {@link ezcImageAnalyzerPhpHandler::analyzeImage()} method:
* @version //autogentag//
* Analyzes the image type.
* This method analyzes image data to determine the MIME type. This method
* returns the MIME type of the file to analyze in lowercase letters (e.g.
* "image/jpeg") or false, if the images MIME type could not be determined.
* For a list of image types this handler will be able to analyze, see
* {@link ezcImageAnalyzerPhpHandler}.
* @param string $file The file to analyze.
* @return string|boolThe MIME type if analyzation suceeded or false.
* Analyze the image for detailed information.
* This may return various information about the image, depending on it's
* type. All information is collected in the struct
* {@link ezcImageAnalyzerData}. At least the
* {@link ezcImageAnalyzerData::$mime} attribute is always available, if the
* image type can be analyzed at all. Additionally this handler will always
* set the {@link ezcImageAnalyzerData::$width},
* {@link ezcImageAnalyzerData::$height} and
* {@link ezcImageAnalyzerData::$size} attributes. For detailes information
* on the additional data returned, see {@link ezcImageAnalyzerPhpHandler}.
* @throws ezcImageAnalyzerFileNotProcessableException
* If image file can not be processed.
* @param string $file The file to analyze.
* @return ezcImageAnalyzerData
'getimagesize() returned false.'
$dataStruct->width =
$data[0];
$dataStruct->height =
$data[1];
if ( ( $dataStruct->mime ===
'image/jpeg' ||
$dataStruct->mime ===
'image/tiff' )
$this->analyzeExif( $file, $dataStruct );
elseif ( $dataStruct->mime ===
'image/gif' )
$this->analyzeGif( $file, $dataStruct );
* Returns if the handler can analyze a given MIME type.
* This method returns if the driver is capable of analyzing a given MIME
* type. This method should be called before trying to actually analyze an
* image using the drivers {@link self::analyzeImage()} method.
* @param string $mime The MIME type to check for.
* @return bool True if the handler is able to analyze the MIME type.
case 'application/x-shockwave-flash':
case 'image/vnd.wap.wbmp':
* Checks wether the GD handler is available on the system.
* Returns if PHP's {@link getimagesize()} function is available.
* @return bool True is the handler is available.
* Analyze EXIF enabled file format for EXIF data entries.
* The image file is analyzed by calling exif_read_data and placing the
* result in self::exif. In addition it fills in extra properties from
* the EXIF data for easy and uniform access.
* @param string $file The file to analyze.
* @param ezcImageAnalyzerData $dataStruct The data struct to fill.
* @return ezcImageAnalyzerData The filled data struct.
private function analyzeExif( $file, ezcImageAnalyzerData $dataStruct )
$dataStruct->exif =
exif_read_data( $file, "COMPUTED,FILE", true, false );
if ( isset
( $dataStruct->exif['COMPUTED']['Width'] ) && isset
( $dataStruct->exif['COMPUTED']['Height'] ) )
$dataStruct->width =
$dataStruct->exif['COMPUTED']['Width'];
$dataStruct->height =
$dataStruct->exif['COMPUTED']['Height'];
if ( isset
( $dataStruct->exif['COMPUTED']['IsColor'] ) )
$dataStruct->isColor =
$dataStruct->exif['COMPUTED']['IsColor'] ==
1;
if ( isset
( $dataStruct->exif['COMPUTED']['UserComment'] ) )
$dataStruct->comment =
$dataStruct->exif['COMPUTED']['UserComment'];
$dataStruct->commentList =
array( $dataStruct->comment );
if ( isset
( $dataStruct->exif['COMPUTED']['Copyright'] ) )
$dataStruct->copyright =
$dataStruct->exif['COMPUTED']['Copyright'];
$dataStruct->hasThumbnail = isset
( $dataStruct->exif['THUMBNAIL'] );
if ( isset
( $dataStruct->exif['FILE']['FileSize'] ) )
$dataStruct->size =
$dataStruct->exif['FILE']['FileSize'];
if ( isset
( $dataStruct->exif['FILE']['FileDateTime'] ) )
$dataStruct->date =
$dataStruct->exif['FILE']['FileDateTime'];
// EXIF based image are never animated.
$dataStruct->isAnimated =
false;
* Analyze GIF files for detailed information.
* The GIF file is analyzed by scanning for frame entries, if more than one
* is found it is assumed to be animated.
* It also extracts other information such as image width and height, color
* count, image mode, transparency type and comments.
* @throws ezcBaseFileIoException
* If image file could not be read.
* @throws ezcImageAnalyzerFileNotProcessableException
* If image file can not be processed.
* @param string $file The file to analyze.
* @param ezcImageAnalyzerData $dataStruct The data struct to fill.
* @return ezcImageAnalyzerData The filled data struct.
private function analyzeGif( $file, ezcImageAnalyzerData $dataStruct )
if ( ( $fp =
fopen( $file, 'rb' ) ) ===
false )
$magic =
fread( $fp, 6 );
if ( $magic !=
'GIF87a' &&
$version =
substr( $magic, 3 );
// Gifs are always indexed
$dataStruct->mode =
self::MODE_INDEXED;
$dataStruct->commentList =
array();
$dataStruct->transparencyType =
self::TRANSPARENCY_OPAQUE;
// Read Logical Screen Descriptor
$data =
unpack( "v1width/v1height/C1bitfield/C1index/C1ration", fread( $fp, 7 ) );
$lsdFields =
$data['bitfield'];
$globalColorTableSize =
0;
// Extract 3 bits for color count
$globalColorCount =
( 1 <<
( ( $lsdFields & 0x07 ) +
1) );
// Each color entry is RGB ie. 3 bytes
$globalColorTableSize =
$globalColorCount *
3;
$dataStruct->colorCount =
$globalColorCount;
$dataStruct->width =
$data['width'];
$dataStruct->height =
$data['height'];
if ( $globalColorTableSize )
// Skip the color table, we don't need the data
fseek( $fp, $globalColorTableSize, SEEK_CUR );
$offset +=
$globalColorTableSize;
// Iterate over all blocks and extract information
$blockType =
ord( $data[0] );
if ( $blockType ==
0x21 ) // Extension Introducer
$data .=
fread( $fp, 1 );
$extensionLabel =
ord( $data[1] );
if ( $extensionLabel ==
0xf9 ) // Graphical Control Extension
$data =
unpack( "C1blocksize/C1bitfield/v1delay/C1index/C1term", fread( $fp, 5 +
1 ) );
$gceFlags =
$data['bitfield'];//ord( $data[1] );
// $animationTimer is currently not in use.
/* $animationTimer = $data['delay']; */
$dataStruct->transparencyType =
self::TRANSPARENCY_TRANSPARENT;
else if ( $extensionLabel ==
0xff ) // Application Extension
$data =
fread( $fp, 12 );
while ( !$dataBlockDone )
$blockBytes =
$data['blocksize'];
// Skip application data, we don't need the data
fseek( $fp, $blockBytes, SEEK_CUR );
else if ( $extensionLabel ==
0xfe ) // Comment Extension
$commentBlockDone =
false;
while ( !$commentBlockDone )
$blockBytes =
$data['blocksize'];
// Append current block to comment
$data =
fread( $fp, $blockBytes );
$commentBlockDone =
true;
if ( $dataStruct->comment ===
null )
$dataStruct->comment =
$comment;
$dataStruct->commentList[] =
$comment;
else if ( $blockType ==
0x2c ) // Image Descriptor
$data .=
fread( $fp, 9 );
$data =
unpack( "C1separator/v1leftpos/v1toppos/v1width/v1height/C1bitfield", $data );
$localColorTableSize =
0;
$idFields =
$data['bitfield'];
if ( $idFields >>
7 ) // Local Color Table
// Extract 3 bits for color count
$localColorCount =
( 1 <<
( ( $idFields & 0x07 ) +
1) );
// Each color entry is RGB ie. 3 bytes
$localColorTableSize =
$localColorCount *
3;
if ( $localColorCount >
$globalColorCount )
$dataStruct->colorCount =
$localColorCount;
if ( $localColorTableSize )
// Skip the color table, we don't need the data
fseek( $fp, $localColorTableSize, SEEK_CUR );
$offset +=
$localColorTableSize;
$lzwCodeSize =
fread( $fp, 1 ); // LZW Minimum Code Size, currently unused
while ( !$dataBlockDone )
$blockBytes =
$data['blocksize'];
// Skip image data, we don't need the data
fseek( $fp, $blockBytes, SEEK_CUR );
else if ( $blockType ==
0x3b ) // Trailer, end of stream
$dataStruct->isAnimated =
$frames >
1;