File indexing completed on 2025-01-19 05:21:23

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Pdf
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /** Internally used classes */
0023 // require_once 'Zend/Pdf/Element/Array.php';
0024 // require_once 'Zend/Pdf/Element/Name.php';
0025 // require_once 'Zend/Pdf/Element/Numeric.php';
0026 
0027 
0028 /** Zend_Pdf_Resource_Image */
0029 // require_once 'Zend/Pdf/Resource/Image.php';
0030 
0031 /**
0032  * TIFF image
0033  *
0034  * @package    Zend_Pdf
0035  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0036  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0037  */
0038 class Zend_Pdf_Resource_Image_Tiff extends Zend_Pdf_Resource_Image
0039 {
0040     const TIFF_FIELD_TYPE_BYTE=1;
0041     const TIFF_FIELD_TYPE_ASCII=2;
0042     const TIFF_FIELD_TYPE_SHORT=3;
0043     const TIFF_FIELD_TYPE_LONG=4;
0044     const TIFF_FIELD_TYPE_RATIONAL=5;
0045 
0046     const TIFF_TAG_IMAGE_WIDTH=256;
0047     const TIFF_TAG_IMAGE_LENGTH=257; //Height
0048     const TIFF_TAG_BITS_PER_SAMPLE=258;
0049     const TIFF_TAG_COMPRESSION=259;
0050     const TIFF_TAG_PHOTOMETRIC_INTERPRETATION=262;
0051     const TIFF_TAG_STRIP_OFFSETS=273;
0052     const TIFF_TAG_SAMPLES_PER_PIXEL=277;
0053     const TIFF_TAG_STRIP_BYTE_COUNTS=279;
0054 
0055     const TIFF_COMPRESSION_UNCOMPRESSED = 1;
0056     const TIFF_COMPRESSION_CCITT1D = 2;
0057     const TIFF_COMPRESSION_GROUP_3_FAX = 3;
0058     const TIFF_COMPRESSION_GROUP_4_FAX  = 4;
0059     const TIFF_COMPRESSION_LZW = 5;
0060     const TIFF_COMPRESSION_JPEG = 6;
0061     const TIFF_COMPRESSION_FLATE = 8;
0062     const TIFF_COMPRESSION_FLATE_OBSOLETE_CODE = 32946;
0063     const TIFF_COMPRESSION_PACKBITS = 32773;
0064 
0065     const TIFF_PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO=0;
0066     const TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO=1;
0067     const TIFF_PHOTOMETRIC_INTERPRETATION_RGB=2;
0068     const TIFF_PHOTOMETRIC_INTERPRETATION_RGB_INDEXED=3;
0069     const TIFF_PHOTOMETRIC_INTERPRETATION_CMYK=5;
0070     const TIFF_PHOTOMETRIC_INTERPRETATION_YCBCR=6;
0071     const TIFF_PHOTOMETRIC_INTERPRETATION_CIELAB=8;
0072 
0073     protected $_width;
0074     protected $_height;
0075     protected $_imageProperties;
0076     protected $_endianType;
0077     protected $_fileSize;
0078     protected $_bitsPerSample;
0079     protected $_compression;
0080     protected $_filter;
0081     protected $_colorCode;
0082     protected $_whiteIsZero;
0083     protected $_blackIsZero;
0084     protected $_colorSpace;
0085     protected $_imageDataOffset;
0086     protected $_imageDataLength;
0087 
0088     const TIFF_ENDIAN_BIG=0;
0089     const TIFF_ENDIAN_LITTLE=1;
0090 
0091     const UNPACK_TYPE_BYTE=0;
0092     const UNPACK_TYPE_SHORT=1;
0093     const UNPACK_TYPE_LONG=2;
0094     const UNPACK_TYPE_RATIONAL=3;
0095 
0096     /**
0097      * Byte unpacking function
0098      *
0099      * Makes it possible to unpack bytes in one statement for enhanced logic readability.
0100      *
0101      * @param int $type
0102      * @param string $bytes
0103      * @throws Zend_Pdf_Exception
0104      */
0105     protected function unpackBytes($type, $bytes) {
0106         if(!isset($this->_endianType)) {
0107             // require_once 'Zend/Pdf/Exception.php';
0108             throw new Zend_Pdf_Exception("The unpackBytes function can only be used after the endianness of the file is known");
0109         }
0110         switch($type) {
0111             case Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_BYTE:
0112                 $format = 'C';
0113                 $unpacked = unpack($format, $bytes);
0114                 return $unpacked[1];
0115                 break;
0116             case Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT:
0117                 $format = ($this->_endianType == Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE)?'v':'n';
0118                 $unpacked = unpack($format, $bytes);
0119                 return $unpacked[1];
0120                 break;
0121             case Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG:
0122                 $format = ($this->_endianType == Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE)?'V':'N';
0123                 $unpacked = unpack($format, $bytes);
0124                 return $unpacked[1];
0125                 break;
0126             case Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_RATIONAL:
0127                 $format = ($this->_endianType == Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE)?'V2':'N2';
0128                 $unpacked = unpack($format, $bytes);
0129                 return ($unpacked[1]/$unpacked[2]);
0130                 break;
0131         }
0132     }
0133 
0134     /**
0135      * Object constructor
0136      *
0137      * @param string $imageFileName
0138      * @throws Zend_Pdf_Exception
0139      */
0140     public function __construct($imageFileName)
0141     {
0142         if (($imageFile = @fopen($imageFileName, 'rb')) === false ) {
0143             // require_once 'Zend/Pdf/Exception.php';
0144             throw new Zend_Pdf_Exception( "Can not open '$imageFileName' file for reading." );
0145         }
0146 
0147         $byteOrderIndicator = fread($imageFile, 2);
0148         if($byteOrderIndicator == 'II') {
0149             $this->_endianType = Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE;
0150         } else if($byteOrderIndicator == 'MM') {
0151             $this->_endianType = Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_BIG;
0152         } else {
0153             // require_once 'Zend/Pdf/Exception.php';
0154             throw new Zend_Pdf_Exception( "Not a tiff file or Tiff corrupt. No byte order indication found" );
0155         }
0156 
0157         $version = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, fread($imageFile, 2));
0158 
0159         if($version != 42) {
0160             // require_once 'Zend/Pdf/Exception.php';
0161             throw new Zend_Pdf_Exception( "Not a tiff file or Tiff corrupt. Incorrect version number." );
0162         }
0163         $ifdOffset = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG, fread($imageFile, 4));
0164 
0165         $fileStats = fstat($imageFile);
0166         $this->_fileSize = $fileStats['size'];
0167 
0168         /*
0169          * Tiff files are stored as a series of Image File Directories (IFD) each direcctory
0170          * has a specific number of entries each 12 bytes in length. At the end of the directories
0171          * is four bytes pointing to the offset of the next IFD.
0172          */
0173 
0174         while($ifdOffset > 0) {
0175             if(fseek($imageFile, $ifdOffset, SEEK_SET) == -1 || $ifdOffset+2 >= $this->_fileSize) {
0176                 // require_once 'Zend/Pdf/Exception.php';
0177                 throw new Zend_Pdf_Exception("Could not seek to the image file directory as indexed by the file. Likely cause is TIFF corruption. Offset: ". $ifdOffset);
0178             }
0179 
0180             $numDirEntries = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, fread($imageFile, 2));
0181 
0182             /*
0183              * Since we now know how many entries are in this (IFD) we can extract the data.
0184              * The format of a TIFF directory entry is:
0185              *
0186              * 2 bytes (short) tag code; See TIFF_TAG constants at the top for supported values. (There are many more in the spec)
0187              * 2 bytes (short) field type
0188              * 4 bytes (long) number of values, or value count.
0189              * 4 bytes (mixed) data if the data will fit into 4 bytes or an offset if the data is too large.
0190              */
0191             for($dirEntryIdx = 1; $dirEntryIdx <= $numDirEntries; $dirEntryIdx++) {
0192                 $tag         = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, fread($imageFile, 2));
0193                 $fieldType   = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, fread($imageFile, 2));
0194                 $valueCount  = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG, fread($imageFile, 4));
0195 
0196                 switch($fieldType) {
0197                     case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_BYTE:
0198                         $fieldLength = $valueCount;
0199                         break;
0200                     case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_ASCII:
0201                         $fieldLength = $valueCount;
0202                         break;
0203                     case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_SHORT:
0204                         $fieldLength = $valueCount * 2;
0205                         break;
0206                     case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_LONG:
0207                         $fieldLength = $valueCount * 4;
0208                         break;
0209                     case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_RATIONAL:
0210                         $fieldLength = $valueCount * 8;
0211                         break;
0212                     default:
0213                         $fieldLength = $valueCount;
0214                 }
0215 
0216                 $offsetBytes = fread($imageFile, 4);
0217 
0218                 if($fieldLength <= 4) {
0219                     switch($fieldType) {
0220                         case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_BYTE:
0221                             $value = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_BYTE, $offsetBytes);
0222                             break;
0223                         case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_ASCII:
0224                             //Fall through to next case
0225                         case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_LONG:
0226                             $value = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG, $offsetBytes);
0227                             break;
0228                         case Zend_Pdf_Resource_Image_Tiff::TIFF_FIELD_TYPE_SHORT:
0229                             //Fall through to next case
0230                         default:
0231                             $value = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, $offsetBytes);
0232                     }
0233                 } else {
0234                     $refOffset = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG, $offsetBytes);
0235                 }
0236                 /*
0237                  * Linear tag processing is probably not the best way to do this. I've processed the tags according to the
0238                  * Tiff 6 specification and make some assumptions about when tags will be < 4 bytes and fit into $value and when
0239                  * they will be > 4 bytes and require seek/extraction of the offset. Same goes for extracting arrays of data, like
0240                  * the data offsets and length. This should be fixed in the future.
0241                  */
0242                 switch($tag) {
0243                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_IMAGE_WIDTH:
0244                         $this->_width = $value;
0245                         break;
0246                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_IMAGE_LENGTH:
0247                         $this->_height = $value;
0248                         break;
0249                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_BITS_PER_SAMPLE:
0250                         if($valueCount>1) {
0251                             $fp = ftell($imageFile);
0252                             fseek($imageFile, $refOffset, SEEK_SET);
0253                             $this->_bitsPerSample = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_SHORT, fread($imageFile, 2));
0254                             fseek($imageFile, $fp, SEEK_SET);
0255                         } else {
0256                             $this->_bitsPerSample = $value;
0257                         }
0258                         break;
0259                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_COMPRESSION:
0260                         $this->_compression = $value;
0261                         switch($value) {
0262                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_UNCOMPRESSED:
0263                                 $this->_filter = 'None';
0264                                 break;
0265                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_CCITT1D:
0266                                 //Fall through to next case
0267                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_GROUP_3_FAX:
0268                                 //Fall through to next case
0269                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_GROUP_4_FAX:
0270                                 $this->_filter = 'CCITTFaxDecode';
0271                                 // require_once 'Zend/Pdf/Exception.php';
0272                                 throw new Zend_Pdf_Exception("CCITTFaxDecode Compression Mode Not Currently Supported");
0273                                 break;
0274                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_LZW:
0275                                 $this->_filter = 'LZWDecode';
0276                                 // require_once 'Zend/Pdf/Exception.php';
0277                                 throw new Zend_Pdf_Exception("LZWDecode Compression Mode Not Currently Supported");
0278                                 break;
0279                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_JPEG:
0280                                 $this->_filter = 'DCTDecode'; //Should work, doesnt...
0281                                 // require_once 'Zend/Pdf/Exception.php';
0282                                 throw new Zend_Pdf_Exception("JPEG Compression Mode Not Currently Supported");
0283                                 break;
0284                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_FLATE:
0285                                 //fall through to next case
0286                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_FLATE_OBSOLETE_CODE:
0287                                 $this->_filter = 'FlateDecode';
0288                                 // require_once 'Zend/Pdf/Exception.php';
0289                                 throw new Zend_Pdf_Exception("ZIP/Flate Compression Mode Not Currently Supported");
0290                                 break;
0291                             case Zend_Pdf_Resource_Image_Tiff::TIFF_COMPRESSION_PACKBITS:
0292                                 $this->_filter = 'RunLengthDecode';
0293                                 break;
0294                         }
0295                         break;
0296                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_PHOTOMETRIC_INTERPRETATION:
0297                         $this->_colorCode = $value;
0298                         $this->_whiteIsZero = false;
0299                         $this->_blackIsZero = false;
0300                         switch($value) {
0301                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO:
0302                                 $this->_whiteIsZero = true;
0303                                 $this->_colorSpace = 'DeviceGray';
0304                                 break;
0305                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO:
0306                                 $this->_blackIsZero = true;
0307                                 $this->_colorSpace = 'DeviceGray';
0308                                 break;
0309                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_YCBCR:
0310                                 //fall through to next case
0311                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_RGB:
0312                                 $this->_colorSpace = 'DeviceRGB';
0313                                 break;
0314                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_RGB_INDEXED:
0315                                 $this->_colorSpace = 'Indexed';
0316                                 break;
0317                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_CMYK:
0318                                 $this->_colorSpace = 'DeviceCMYK';
0319                                 break;
0320                             case Zend_Pdf_Resource_Image_Tiff::TIFF_PHOTOMETRIC_INTERPRETATION_CIELAB:
0321                                 $this->_colorSpace = 'Lab';
0322                                 break;
0323                             default:
0324                                 // require_once 'Zend/Pdf/Exception.php';
0325                                 throw new Zend_Pdf_Exception('TIFF: Unknown or Unsupported Color Type: '. $value);
0326                         }
0327                         break;
0328                     case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_STRIP_OFFSETS:
0329                         if($valueCount>1) {
0330                             $format = ($this->_endianType == Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE)?'V*':'N*';
0331                             $fp = ftell($imageFile);
0332                             fseek($imageFile, $refOffset, SEEK_SET);
0333                             $stripOffsetsBytes = fread($imageFile, $fieldLength);
0334                             $this->_imageDataOffset = unpack($format, $stripOffsetsBytes);
0335                             fseek($imageFile, $fp, SEEK_SET);
0336                         } else {
0337                             $this->_imageDataOffset = $value;
0338                         }
0339                         break;
0340                    case Zend_Pdf_Resource_Image_Tiff::TIFF_TAG_STRIP_BYTE_COUNTS:
0341                         if($valueCount>1) {
0342                             $format = ($this->_endianType == Zend_Pdf_Resource_Image_Tiff::TIFF_ENDIAN_LITTLE)?'V*':'N*';
0343                             $fp = ftell($imageFile);
0344                             fseek($imageFile, $refOffset, SEEK_SET);
0345                             $stripByteCountsBytes = fread($imageFile, $fieldLength);
0346                             $this->_imageDataLength = unpack($format, $stripByteCountsBytes);
0347                             fseek($imageFile, $fp, SEEK_SET);
0348                         } else {
0349                             $this->_imageDataLength = $value;
0350                         }
0351                         break;
0352                     default:
0353                         //For debugging. It should be harmless to ignore unknown tags, though there is some good info in them.
0354                         //echo "Unknown tag detected: ". $tag . " value: ". $value;
0355                 }
0356             }
0357             $ifdOffset = $this->unpackBytes(Zend_Pdf_Resource_Image_Tiff::UNPACK_TYPE_LONG, fread($imageFile, 4));
0358         }
0359 
0360         if(!isset($this->_imageDataOffset) || !isset($this->_imageDataLength)) {
0361             // require_once 'Zend/Pdf/Exception.php';
0362             throw new Zend_Pdf_Exception("TIFF: The image processed did not contain image data as expected.");
0363         }
0364 
0365         $imageDataBytes = '';
0366         if(is_array($this->_imageDataOffset)) {
0367             if(!is_array($this->_imageDataLength)) {
0368                 // require_once 'Zend/Pdf/Exception.php';
0369                 throw new Zend_Pdf_Exception("TIFF: The image contained multiple data offsets but not multiple data lengths. Tiff may be corrupt.");
0370             }
0371             foreach($this->_imageDataOffset as $idx => $offset) {
0372                 fseek($imageFile, $this->_imageDataOffset[$idx], SEEK_SET);
0373                 $imageDataBytes .= fread($imageFile, $this->_imageDataLength[$idx]);
0374             }
0375         } else {
0376             fseek($imageFile, $this->_imageDataOffset, SEEK_SET);
0377             $imageDataBytes = fread($imageFile, $this->_imageDataLength);
0378         }
0379         if($imageDataBytes === '') {
0380             // require_once 'Zend/Pdf/Exception.php';
0381             throw new Zend_Pdf_Exception("TIFF: No data. Image Corruption");
0382         }
0383 
0384         fclose($imageFile);
0385 
0386         parent::__construct();
0387 
0388         $imageDictionary = $this->_resource->dictionary;
0389         if(!isset($this->_width) || !isset($this->_width)) {
0390             // require_once 'Zend/Pdf/Exception.php';
0391             throw new Zend_Pdf_Exception("Problem reading tiff file. Tiff is probably corrupt.");
0392         }
0393 
0394         $this->_imageProperties = array();
0395         $this->_imageProperties['bitDepth'] = $this->_bitsPerSample;
0396         $this->_imageProperties['fileSize'] = $this->_fileSize;
0397         $this->_imageProperties['TIFFendianType'] = $this->_endianType;
0398         $this->_imageProperties['TIFFcompressionType'] = $this->_compression;
0399         $this->_imageProperties['TIFFwhiteIsZero'] = $this->_whiteIsZero;
0400         $this->_imageProperties['TIFFblackIsZero'] = $this->_blackIsZero;
0401         $this->_imageProperties['TIFFcolorCode'] = $this->_colorCode;
0402         $this->_imageProperties['TIFFimageDataOffset'] = $this->_imageDataOffset;
0403         $this->_imageProperties['TIFFimageDataLength'] = $this->_imageDataLength;
0404         $this->_imageProperties['PDFfilter'] = $this->_filter;
0405         $this->_imageProperties['PDFcolorSpace'] = $this->_colorSpace;
0406 
0407         $imageDictionary->Width            = new Zend_Pdf_Element_Numeric($this->_width);
0408         if($this->_whiteIsZero === true) {
0409             $imageDictionary->Decode       = new Zend_Pdf_Element_Array(array(new Zend_Pdf_Element_Numeric(1), new Zend_Pdf_Element_Numeric(0)));
0410         }
0411         $imageDictionary->Height           = new Zend_Pdf_Element_Numeric($this->_height);
0412         $imageDictionary->ColorSpace       = new Zend_Pdf_Element_Name($this->_colorSpace);
0413         $imageDictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($this->_bitsPerSample);
0414         if(isset($this->_filter) && $this->_filter != 'None') {
0415             $imageDictionary->Filter = new Zend_Pdf_Element_Name($this->_filter);
0416         }
0417 
0418         $this->_resource->value = $imageDataBytes;
0419         $this->_resource->skipFilters();
0420     }
0421     /**
0422      * Image width (defined in Zend_Pdf_Resource_Image_Interface)
0423      */
0424     public function getPixelWidth() {
0425         return $this->_width;
0426     }
0427 
0428     /**
0429      * Image height (defined in Zend_Pdf_Resource_Image_Interface)
0430      */
0431     public function getPixelHeight() {
0432         return $this->_height;
0433     }
0434 
0435     /**
0436      * Image properties (defined in Zend_Pdf_Resource_Image_Interface)
0437      */
0438     public function getProperties() {
0439         return $this->_imageProperties;
0440     }
0441 }
0442