Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Public Member Functions | Data Fields | Protected Attributes
Zend_Pdf_Resource_Image_Png Class Reference
Inheritance diagram for Zend_Pdf_Resource_Image_Png:
Zend_Pdf_Resource_Image Zend_Pdf_Resource

Public Member Functions

 __construct ($imageFileName)
 
 getPixelWidth ()
 
 getPixelHeight ()
 
 getProperties ()
 
- Public Member Functions inherited from Zend_Pdf_Resource_Image
 __construct ()
 
 getPixelHeight ()
 
 getPixelWidth ()
 
 getProperties ()
 
- Public Member Functions inherited from Zend_Pdf_Resource
 __construct ($resource)
 
 __clone ()
 
 cloneResource ($factory, &$processed)
 
 getResource ()
 
 getFactory ()
 

Data Fields

const PNG_COMPRESSION_DEFAULT_STRATEGY = 0
 
const PNG_COMPRESSION_FILTERED = 1
 
const PNG_COMPRESSION_HUFFMAN_ONLY = 2
 
const PNG_COMPRESSION_RLE = 3
 
const PNG_FILTER_NONE = 0
 
const PNG_FILTER_SUB = 1
 
const PNG_FILTER_UP = 2
 
const PNG_FILTER_AVERAGE = 3
 
const PNG_FILTER_PAETH = 4
 
const PNG_INTERLACING_DISABLED = 0
 
const PNG_INTERLACING_ENABLED = 1
 
const PNG_CHANNEL_GRAY = 0
 
const PNG_CHANNEL_RGB = 2
 
const PNG_CHANNEL_INDEXED = 3
 
const PNG_CHANNEL_GRAY_ALPHA = 4
 
const PNG_CHANNEL_RGB_ALPHA = 6
 

Protected Attributes

 $_width
 
 $_height
 
 $_imageProperties
 
- Protected Attributes inherited from Zend_Pdf_Resource
 $_objectFactory
 
 $_resource
 

Detailed Description

Definition at line 41 of file Png.php.

Constructor & Destructor Documentation

◆ __construct()

__construct (   $imageFileName)

Object constructor

Parameters
string$imageFileName
Exceptions
Zend_Pdf_Exception
Todo:

Add compression conversions to support compression strategys other than PNG_COMPRESSION_DEFAULT_STRATEGY.

Add pre-compression filtering.

Add interlaced image handling.

Add support for 16-bit images. Requires PDF version bump to 1.5 at least.

Add processing for all PNG chunks defined in the spec. gAMA etc.

Fix tRNS chunk support for Indexed Images to a SMask.

Definition at line 79 of file Png.php.

80  {
81  if (($imageFile = @fopen($imageFileName, 'rb')) === false ) {
82  #require_once 'Zend/Pdf/Exception.php';
83  throw new Zend_Pdf_Exception( "Can not open '$imageFileName' file for reading." );
84  }
85 
86  parent::__construct();
87 
88  //Check if the file is a PNG
89  fseek($imageFile, 1, SEEK_CUR); //First signature byte (%)
90  if ('PNG' != fread($imageFile, 3)) {
91  #require_once 'Zend/Pdf/Exception.php';
92  throw new Zend_Pdf_Exception('Image is not a PNG');
93  }
94  fseek($imageFile, 12, SEEK_CUR); //Signature bytes (Includes the IHDR chunk) IHDR processed linerarly because it doesnt contain a variable chunk length
95  $wtmp = unpack('Ni',fread($imageFile, 4)); //Unpack a 4-Byte Long
96  $width = $wtmp['i'];
97  $htmp = unpack('Ni',fread($imageFile, 4));
98  $height = $htmp['i'];
99  $bits = ord(fread($imageFile, 1)); //Higher than 8 bit depths are only supported in later versions of PDF.
100  $color = ord(fread($imageFile, 1));
101 
102  $compression = ord(fread($imageFile, 1));
103  $prefilter = ord(fread($imageFile,1));
104 
105  if (($interlacing = ord(fread($imageFile,1))) != Zend_Pdf_Resource_Image_Png::PNG_INTERLACING_DISABLED) {
106  #require_once 'Zend/Pdf/Exception.php';
107  throw new Zend_Pdf_Exception( "Only non-interlaced images are currently supported." );
108  }
109 
110  $this->_width = $width;
111  $this->_height = $height;
112  $this->_imageProperties = array();
113  $this->_imageProperties['bitDepth'] = $bits;
114  $this->_imageProperties['pngColorType'] = $color;
115  $this->_imageProperties['pngFilterType'] = $prefilter;
116  $this->_imageProperties['pngCompressionType'] = $compression;
117  $this->_imageProperties['pngInterlacingType'] = $interlacing;
118 
119  fseek($imageFile, 4, SEEK_CUR); //4 Byte Ending Sequence
120  $imageData = '';
121 
122  /*
123  * The following loop processes PNG chunks. 4 Byte Longs are packed first give the chunk length
124  * followed by the chunk signature, a four byte code. IDAT and IEND are manditory in any PNG.
125  */
126  while (!feof($imageFile)) {
127  $chunkLengthBytes = fread($imageFile, 4);
128  if ($chunkLengthBytes === false) {
129  #require_once 'Zend/Pdf/Exception.php';
130  throw new Zend_Pdf_Exception('Error ocuured while image file reading.');
131  }
132 
133  $chunkLengthtmp = unpack('Ni', $chunkLengthBytes);
134  $chunkLength = $chunkLengthtmp['i'];
135  $chunkType = fread($imageFile, 4);
136  switch($chunkType) {
137  case 'IDAT': //Image Data
138  /*
139  * Reads the actual image data from the PNG file. Since we know at this point that the compression
140  * strategy is the default strategy, we also know that this data is Zip compressed. We will either copy
141  * the data directly to the PDF and provide the correct FlateDecode predictor, or decompress the data
142  * decode the filters and output the data as a raw pixel map.
143  */
144  $imageData .= fread($imageFile, $chunkLength);
145  fseek($imageFile, 4, SEEK_CUR);
146  break;
147 
148  case 'PLTE': //Palette
149  $paletteData = fread($imageFile, $chunkLength);
150  fseek($imageFile, 4, SEEK_CUR);
151  break;
152 
153  case 'tRNS': //Basic (non-alpha channel) transparency.
154  $trnsData = fread($imageFile, $chunkLength);
155  switch ($color) {
157  $baseColor = ord(substr($trnsData, 1, 1));
158  $transparencyData = array(new Zend_Pdf_Element_Numeric($baseColor),
159  new Zend_Pdf_Element_Numeric($baseColor));
160  break;
161 
163  $red = ord(substr($trnsData,1,1));
164  $green = ord(substr($trnsData,3,1));
165  $blue = ord(substr($trnsData,5,1));
166  $transparencyData = array(new Zend_Pdf_Element_Numeric($red),
167  new Zend_Pdf_Element_Numeric($red),
168  new Zend_Pdf_Element_Numeric($green),
169  new Zend_Pdf_Element_Numeric($green),
170  new Zend_Pdf_Element_Numeric($blue),
171  new Zend_Pdf_Element_Numeric($blue));
172  break;
173 
175  //Find the first transparent color in the index, we will mask that. (This is a bit of a hack. This should be a SMask and mask all entries values).
176  if(($trnsIdx = strpos($trnsData, "\0")) !== false) {
177  $transparencyData = array(new Zend_Pdf_Element_Numeric($trnsIdx),
178  new Zend_Pdf_Element_Numeric($trnsIdx));
179  }
180  break;
181 
183  // Fall through to the next case
184 
186  #require_once 'Zend/Pdf/Exception.php';
187  throw new Zend_Pdf_Exception( "tRNS chunk illegal for Alpha Channel Images" );
188  break;
189  }
190  fseek($imageFile, 4, SEEK_CUR); //4 Byte Ending Sequence
191  break;
192 
193  case 'IEND';
194  break 2; //End the loop too
195 
196  default:
197  fseek($imageFile, $chunkLength + 4, SEEK_CUR); //Skip the section
198  break;
199  }
200  }
201  fclose($imageFile);
202 
203  $compressed = true;
204  $imageDataTmp = '';
205  $smaskData = '';
206  switch ($color) {
208  $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
209  break;
210 
212  $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
213  break;
214 
216  if(empty($paletteData)) {
217  #require_once 'Zend/Pdf/Exception.php';
218  throw new Zend_Pdf_Exception( "PNG Corruption: No palette data read for indexed type PNG." );
219  }
220  $colorSpace = new Zend_Pdf_Element_Array();
221  $colorSpace->items[] = new Zend_Pdf_Element_Name('Indexed');
222  $colorSpace->items[] = new Zend_Pdf_Element_Name('DeviceRGB');
223  $colorSpace->items[] = new Zend_Pdf_Element_Numeric((strlen($paletteData)/3-1));
224  $paletteObject = $this->_objectFactory->newObject(new Zend_Pdf_Element_String_Binary($paletteData));
225  $colorSpace->items[] = $paletteObject;
226  break;
227 
229  /*
230  * To decode PNG's with alpha data we must create two images from one. One image will contain the Gray data
231  * the other will contain the Gray transparency overlay data. The former will become the object data and the latter
232  * will become the Shadow Mask (SMask).
233  */
234  if($bits > 8) {
235  #require_once 'Zend/Pdf/Exception.php';
236  throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
237  }
238 
239  $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
240 
241  #require_once 'Zend/Pdf/ElementFactory.php';
242  $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
243  $decodingStream = $decodingObjFactory->newStreamObject($imageData);
244  $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
245  $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
246  $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
247  $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
248  $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(2); //GreyAlpha
249  $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
250  $decodingStream->skipFilters();
251 
252  $pngDataRawDecoded = $decodingStream->value;
253 
254  //Iterate every pixel and copy out gray data and alpha channel (this will be slow)
255  for($pixel = 0, $pixelcount = ($width * $height); $pixel < $pixelcount; $pixel++) {
256  $imageDataTmp .= $pngDataRawDecoded[($pixel*2)];
257  $smaskData .= $pngDataRawDecoded[($pixel*2)+1];
258  }
259  $compressed = false;
260  $imageData = $imageDataTmp; //Overwrite image data with the gray channel without alpha
261  break;
262 
264  /*
265  * To decode PNG's with alpha data we must create two images from one. One image will contain the RGB data
266  * the other will contain the Gray transparency overlay data. The former will become the object data and the latter
267  * will become the Shadow Mask (SMask).
268  */
269  if($bits > 8) {
270  #require_once 'Zend/Pdf/Exception.php';
271  throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
272  }
273 
274  $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
275 
276  #require_once 'Zend/Pdf/ElementFactory.php';
277  $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
278  $decodingStream = $decodingObjFactory->newStreamObject($imageData);
279  $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
280  $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
281  $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
282  $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
283  $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(4); //RGBA
284  $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
285  $decodingStream->skipFilters();
286 
287  $pngDataRawDecoded = $decodingStream->value;
288 
289  //Iterate every pixel and copy out rgb data and alpha channel (this will be slow)
290  for($pixel = 0, $pixelcount = ($width * $height); $pixel < $pixelcount; $pixel++) {
291  $imageDataTmp .= $pngDataRawDecoded[($pixel*4)+0] . $pngDataRawDecoded[($pixel*4)+1] . $pngDataRawDecoded[($pixel*4)+2];
292  $smaskData .= $pngDataRawDecoded[($pixel*4)+3];
293  }
294 
295  $compressed = false;
296  $imageData = $imageDataTmp; //Overwrite image data with the RGB channel without alpha
297  break;
298 
299  default:
300  #require_once 'Zend/Pdf/Exception.php';
301  throw new Zend_Pdf_Exception( "PNG Corruption: Invalid color space." );
302  }
303 
304  if(empty($imageData)) {
305  #require_once 'Zend/Pdf/Exception.php';
306  throw new Zend_Pdf_Exception( "Corrupt PNG Image. Mandatory IDAT chunk not found." );
307  }
308 
309  $imageDictionary = $this->_resource->dictionary;
310  if(!empty($smaskData)) {
311  /*
312  * Includes the Alpha transparency data as a Gray Image, then assigns the image as the Shadow Mask for the main image data.
313  */
314  $smaskStream = $this->_objectFactory->newStreamObject($smaskData);
315  $smaskStream->dictionary->Type = new Zend_Pdf_Element_Name('XObject');
316  $smaskStream->dictionary->Subtype = new Zend_Pdf_Element_Name('Image');
317  $smaskStream->dictionary->Width = new Zend_Pdf_Element_Numeric($width);
318  $smaskStream->dictionary->Height = new Zend_Pdf_Element_Numeric($height);
319  $smaskStream->dictionary->ColorSpace = new Zend_Pdf_Element_Name('DeviceGray');
320  $smaskStream->dictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
321  $imageDictionary->SMask = $smaskStream;
322 
323  // Encode stream with FlateDecode filter
324  $smaskStreamDecodeParms = array();
325  $smaskStreamDecodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15);
326  $smaskStreamDecodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
327  $smaskStreamDecodeParms['Colors'] = new Zend_Pdf_Element_Numeric(1);
328  $smaskStreamDecodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric(8);
329  $smaskStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($smaskStreamDecodeParms);
330  $smaskStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
331  }
332 
333  if(!empty($transparencyData)) {
334  //This is experimental and not properly tested.
335  $imageDictionary->Mask = new Zend_Pdf_Element_Array($transparencyData);
336  }
337 
338  $imageDictionary->Width = new Zend_Pdf_Element_Numeric($width);
339  $imageDictionary->Height = new Zend_Pdf_Element_Numeric($height);
340  $imageDictionary->ColorSpace = $colorSpace;
341  $imageDictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
342  $imageDictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
343 
344  $decodeParms = array();
345  $decodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15); // Optimal prediction
346  $decodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
348  $decodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric($bits);
349  $imageDictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($decodeParms);
350 
351  //Include only the image IDAT section data.
352  $this->_resource->value = $imageData;
353 
354  //Skip double compression
355  if ($compressed) {
356  $this->_resource->skipFilters();
357  }
358  }
const PNG_CHANNEL_GRAY_ALPHA
Definition: Png.php:60
const PNG_INTERLACING_DISABLED
Definition: Png.php:54
static createFactory($objCount)

Member Function Documentation

◆ getPixelHeight()

getPixelHeight ( )

Image height

Definition at line 370 of file Png.php.

370  {
371  return $this->_height;
372  }

◆ getPixelWidth()

getPixelWidth ( )

Image width

Definition at line 363 of file Png.php.

363  {
364  return $this->_width;
365  }

◆ getProperties()

getProperties ( )

Image properties

Definition at line 377 of file Png.php.

377  {
379  }

Field Documentation

◆ $_height

$_height
protected

Definition at line 64 of file Png.php.

◆ $_imageProperties

$_imageProperties
protected

Definition at line 65 of file Png.php.

◆ $_width

$_width
protected

Definition at line 63 of file Png.php.

◆ PNG_CHANNEL_GRAY

const PNG_CHANNEL_GRAY = 0

Definition at line 57 of file Png.php.

◆ PNG_CHANNEL_GRAY_ALPHA

const PNG_CHANNEL_GRAY_ALPHA = 4

Definition at line 60 of file Png.php.

◆ PNG_CHANNEL_INDEXED

const PNG_CHANNEL_INDEXED = 3

Definition at line 59 of file Png.php.

◆ PNG_CHANNEL_RGB

const PNG_CHANNEL_RGB = 2

Definition at line 58 of file Png.php.

◆ PNG_CHANNEL_RGB_ALPHA

const PNG_CHANNEL_RGB_ALPHA = 6

Definition at line 61 of file Png.php.

◆ PNG_COMPRESSION_DEFAULT_STRATEGY

const PNG_COMPRESSION_DEFAULT_STRATEGY = 0

Definition at line 43 of file Png.php.

◆ PNG_COMPRESSION_FILTERED

const PNG_COMPRESSION_FILTERED = 1

Definition at line 44 of file Png.php.

◆ PNG_COMPRESSION_HUFFMAN_ONLY

const PNG_COMPRESSION_HUFFMAN_ONLY = 2

Definition at line 45 of file Png.php.

◆ PNG_COMPRESSION_RLE

const PNG_COMPRESSION_RLE = 3

Definition at line 46 of file Png.php.

◆ PNG_FILTER_AVERAGE

const PNG_FILTER_AVERAGE = 3

Definition at line 51 of file Png.php.

◆ PNG_FILTER_NONE

const PNG_FILTER_NONE = 0

Definition at line 48 of file Png.php.

◆ PNG_FILTER_PAETH

const PNG_FILTER_PAETH = 4

Definition at line 52 of file Png.php.

◆ PNG_FILTER_SUB

const PNG_FILTER_SUB = 1

Definition at line 49 of file Png.php.

◆ PNG_FILTER_UP

const PNG_FILTER_UP = 2

Definition at line 50 of file Png.php.

◆ PNG_INTERLACING_DISABLED

const PNG_INTERLACING_DISABLED = 0

Definition at line 54 of file Png.php.

◆ PNG_INTERLACING_ENABLED

const PNG_INTERLACING_ENABLED = 1

Definition at line 55 of file Png.php.


The documentation for this class was generated from the following file: