Overview

Packages

  • Image
  • None

Classes

  • Horde_Image
  • Horde_Image_Base
  • Horde_Image_Effect
  • Horde_Image_Effect_Border
  • Horde_Image_Effect_Gd_DropShadow
  • Horde_Image_Effect_Gd_RoundCorners
  • Horde_Image_Effect_Gd_TextWatermark
  • Horde_Image_Effect_Gd_Unsharpmask
  • Horde_Image_Effect_Im_Border
  • Horde_Image_Effect_Im_CenterCrop
  • Horde_Image_Effect_Im_Composite
  • Horde_Image_Effect_Im_DropShadow
  • Horde_Image_Effect_Im_LiquidResize
  • Horde_Image_Effect_Im_PhotoStack
  • Horde_Image_Effect_Im_PolaroidImage
  • Horde_Image_Effect_Im_RoundCorners
  • Horde_Image_Effect_Im_TextWatermark
  • Horde_Image_Effect_Im_Unsharpmask
  • Horde_Image_Effect_Imagick_Border
  • Horde_Image_Effect_Imagick_CenterCrop
  • Horde_Image_Effect_Imagick_Composite
  • Horde_Image_Effect_Imagick_DropShadow
  • Horde_Image_Effect_Imagick_LiquidResize
  • Horde_Image_Effect_Imagick_PhotoStack
  • Horde_Image_Effect_Imagick_PolaroidImage
  • Horde_Image_Effect_Imagick_RoundCorners
  • Horde_Image_Effect_Imagick_SmartCrop
  • Horde_Image_Effect_Imagick_TextWatermark
  • Horde_Image_Effect_Imagick_Unsharpmask
  • Horde_Image_Exception
  • Horde_Image_Exif
  • Horde_Image_Exif_Base
  • Horde_Image_Exif_Bundled
  • Horde_Image_Exif_Exiftool
  • Horde_Image_Exif_Parser_Base
  • Horde_Image_Exif_Php
  • Horde_Image_Gd
  • Horde_Image_Im
  • Horde_Image_Imagick
  • Horde_Image_Png
  • Horde_Image_Svg
  • Horde_Image_Swf
  • Horde_Image_Translation
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * This class implements the Horde_Image:: API for PNG images. It
  4:  * mainly provides some utility functions, such as the ability to make
  5:  * pixels or solid images for now.
  6:  *
  7:  * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
  8:  *
  9:  * See the enclosed file COPYING for license information (LGPL). If you
 10:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 11:  *
 12:  * @author  Mike Cochrane <mike@graftonhall.co.nz>
 13:  * @package Image
 14:  */
 15: class Horde_Image_Png extends Horde_Image_Base {
 16: 
 17:     /**
 18:      * The array of pixel data.
 19:      *
 20:      * @var array
 21:      */
 22:     var $_img = array();
 23: 
 24:     /**
 25:      * Color depth (only 8 and 16 implemented).
 26:      *
 27:      * @var integer
 28:      */
 29:     var $_colorDepth = 8;
 30: 
 31:     /**
 32:      * Color type (only 2 (true color) implemented).
 33:      *
 34:      * @var integer
 35:      */
 36:     var $_colorType = 2;
 37: 
 38:     /**
 39:      * Compression method (0 is the only current valid value).
 40:      *
 41:      * @var integer
 42:      */
 43:     var $_compressionMethod = 0;
 44: 
 45:     /**
 46:      * Filter method (0 is the only current valid value).
 47:      *
 48:      * @var integer
 49:      */
 50:     var $_filterMethod = 0;
 51: 
 52:     /**
 53:      * Interlace method (only 0 (no interlace) implemented).
 54:      *
 55:      * @var integer
 56:      */
 57:     var $_interlaceMethod = 0;
 58: 
 59:     /**
 60:      * PNG image constructor.
 61:      */
 62:     public function __construct($params, $context = array())
 63:     {
 64:         parent::__construct($params, $context);
 65: 
 66:         if (!empty($params['width'])) {
 67:             $this->rectangle(0, 0, $params['width'], $params['height'], $this->_background, $this->_background);
 68:         }
 69:     }
 70: 
 71:     function getContentType()
 72:     {
 73:         return 'image/png';
 74:     }
 75: 
 76:     /**
 77:      * Return the raw data for this image.
 78:      *
 79:      * @return string  The raw image data.
 80:      */
 81:     function raw()
 82:     {
 83:         return
 84:             $this->_header() .
 85:             $this->_IHDR() .
 86: 
 87:             /* Say what created the image file. */
 88:             $this->_tEXt('Software', 'Horde Framework Image_png Class') .
 89: 
 90:             /* Set the last modified date/time. */
 91:             $this->_tIME() .
 92: 
 93:             $this->_IDAT() .
 94:             $this->_IEND();
 95:     }
 96: 
 97:     /**
 98:      * Reset the image data.
 99:      */
100:     function reset()
101:     {
102:         parent::reset();
103:         $this->_img = array();
104:     }
105: 
106:     /**
107:      * Draw a rectangle.
108:      *
109:      * @param integer $x       The left x-coordinate of the rectangle.
110:      * @param integer $y       The top y-coordinate of the rectangle.
111:      * @param integer $width   The width of the rectangle.
112:      * @param integer $height  The height of the rectangle.
113:      * @param string $color    The line color of the rectangle.
114:      * @param string $fill     The color to fill the rectangle with.
115:      */
116:     function rectangle($x, $y, $width, $height, $color = 'black', $fill = 'none')
117:     {
118:         list($r, $g, $b) = Horde_Image::getRGB($color);
119:         if ($fill != 'none') {
120:             list($fR, $fG, $fB) = Horde_Image::getRGB($fill);
121:         }
122: 
123:         $x2 = $x + $width;
124:         $y2 = $y + $height;
125: 
126:         for ($h = $y; $h <= $y2; $h++) {
127:             for ($w = $x; $w <= $x2; $w++) {
128:                 // See if we're on an edge.
129:                 if ($w == $x || $h == $y || $w == $x2 || $h == $y2) {
130:                     $this->_img[$h][$w] = array('r' => $r, 'g' => $g, 'b' => $b);
131:                 } elseif ($fill != 'none') {
132:                     $this->_img[$h][$w] = array('r' => $fR, 'g' => $fG, 'b' => $fB);
133:                 }
134:             }
135:         }
136:     }
137: 
138:     /**
139:      * Create the PNG file header.
140:      */
141:     function _header()
142:     {
143:         return pack('CCCCCCCC', 137, 80, 78, 71, 13, 10, 26, 10);
144:     }
145: 
146:     /**
147:      * Create Image Header block.
148:      */
149:     function _IHDR()
150:     {
151:         $data = pack('a4NNCCCCC', 'IHDR', $this->_width, $this->_height, $this->_colorDepth, $this->_colorType, $this->_compressionMethod, $this->_filterMethod, $this->_interlaceMethod);
152:         return pack('Na' . strlen($data) . 'N', strlen($data) - 4, $data, crc32($data));
153:     }
154: 
155:     /**
156:      * Create IEND block.
157:      */
158:     function _IEND()
159:     {
160:         $data = 'IEND';
161:         return pack('Na' . strlen($data) . 'N', strlen($data) - 4, $data, crc32($data));
162:     }
163: 
164:     /**
165:      * Create Image Data block.
166:      */
167:     function _IDAT()
168:     {
169:         $data = '';
170:         $prevscanline = null;
171:         $filter = 0;
172:         for ($i = 0; $i < $this->_height; $i++) {
173:             $scanline = array();
174:             $data .= chr($filter);
175:             for ($j = 0; $j < $this->_width; $j++) {
176:                 if ($this->_colorDepth == 8) {
177:                     $scanline[$j] = pack('CCC', $this->_img[$i][$j]['r'], $this->_img[$i][$j]['g'], $this->_img[$i][$j]['b']);
178:                 } elseif ($this->_colorDepth == 16) {
179:                     $scanline[$j] = pack('nnn', $this->_img[$i][$j]['r'] << 8, $this->_img[$i][$j]['g'] << 8, $this->_img[$i][$j]['b'] << 8);
180:                 }
181: 
182:                 if ($filter == 0) {
183:                     /* No Filter. */
184:                     $data .= $scanline[$j];
185:                 } elseif ($filter == 2) {
186:                     /* Up Filter. */
187:                     $pixel = $scanline[$j] - $prevscanline[$j];
188:                     if ($this->_colorDepth == 8) {
189:                         $data .= pack('CCC', $pixel >> 16, ($pixel >> 8) & 0xFF, $pixel & 0xFF);
190:                     } elseif ($this->_colorDepth == 16) {
191:                         $data .= pack('nnn', ($pixel >> 32), ($pixel >> 16) & 0xFFFF, $pixel & 0xFFFF);
192:                     }
193:                 }
194:             }
195:             $prevscanline = $scanline;
196:         }
197:         $compressed = gzdeflate($data, 9);
198: 
199:         $data = 'IDAT' . pack('CCa' . strlen($compressed) . 'a4', 0x78, 0x01, $compressed, $this->_Adler32($data));
200:         return pack('Na' . strlen($data) . 'N', strlen($data) - 4, $data, crc32($data));
201:     }
202: 
203:     /**
204:      * Create tEXt block.
205:      */
206:     function _tEXt($keyword, $text)
207:     {
208:         $data = 'tEXt' . $keyword . "\0" . $text;
209:         return pack('Na' . strlen($data) . 'N', strlen($data) - 4, $data, crc32($data));
210:     }
211: 
212:     /**
213:      * Create last modified time block.
214:      */
215:     function _tIME($date = null)
216:     {
217:         if (is_null($date)) {
218:             $date = time();
219:         }
220: 
221:         $data = 'tIME' . pack('nCCCCC', intval(date('Y', $date)), intval(date('m', $date)), intval(date('j', $date)), intval(date('G', $date)), intval(date('i', $date)), intval(date('s', $date)));
222:         return pack('Na' . strlen($data) . 'N', strlen($data) - 4, $data, crc32($data));
223:     }
224: 
225:     /**
226:      * Calculate an Adler32 checksum for a string.
227:      */
228:     function _Adler32($input)
229:     {
230:         $s1 = 1;
231:         $s2 = 0;
232:         $iMax = strlen($input);
233:         for ($i = 0; $i < $iMax; $i++) {
234:             $s1 = ($s1 + ord($input[$i])) % 0xFFF1;
235:             $s2 = ($s2 + $s1) % 0xFFF1;
236:         }
237:         return pack('N', (($s2 << 16) | $s1));
238:     }
239: 
240:     /**
241:      * Request a specific image from the collection of images.
242:      *
243:      * @param integer $index  The index to return
244:      *
245:      * @return Horde_Image_Base
246:      * @throws Horde_Image_Exception
247:      */
248:     public function getImageAtIndex($index)
249:     {
250:         if ($index > 0) {
251:             throw new Horde_Image_Exception('Image index out of bounds.');
252:         }
253: 
254:         return clone($this);
255:     }
256: 
257:     /**
258:      * Return the number of image pages available in the image object.
259:      *
260:      * @return integer
261:      */
262:     public function getImagePageCount()
263:     {
264:         return 1;
265:     }
266: 
267: }
268: 
API documentation generated by ApiGen