Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
TypeJpeg.php
001 <?php
002
003 /**
004 * fast-image-size image type jpeg
005 * @package fast-image-size
006 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace FastImageSize\Type;
013
014 class TypeJpeg extends TypeBase
015 {
016 /** @var int JPEG max header size. Headers can be bigger, but we'll abort
017 * going through the header after this */
018 const JPEG_MAX_HEADER_SIZE = 124576;
019
020 /** @var string JPEG header */
021 const JPEG_HEADER = "\xFF\xD8";
022
023 /** @var string Start of frame marker */
024 const SOF_START_MARKER = "\xFF";
025
026 /** @var array JPEG SOF markers */
027 protected $sofMarkers = array(
028 "\xC0",
029 "\xC1",
030 "\xC2",
031 "\xC3",
032 "\xC5",
033 "\xC6",
034 "\xC7",
035 "\xC8",
036 "\xC9",
037 "\xCA",
038 "\xCB",
039 "\xCD",
040 "\xCE",
041 "\xCF"
042 );
043
044 /** @var array JPEG APP markers */
045 protected $appMarkers = array(
046 "\xE0",
047 "\xE1",
048 "\xE2",
049 "\xE3",
050 "\xEC",
051 "\xED",
052 "\xEE",
053 );
054
055 /** @var string|bool $data JPEG data stream */
056 protected $data = '';
057
058 /** @var bool Flag whether exif was found */
059 protected $foundExif = false;
060
061 /** @var bool Flag whether xmp was found */
062 protected $foundXmp = false;
063
064 /**
065 * {@inheritdoc}
066 */
067 public function getSize($filename)
068 {
069 // Do not force the data length
070 $this->data = $this->fastImageSize->getImage($filename, 0, self::JPEG_MAX_HEADER_SIZE, false);
071
072 // Check if file is jpeg
073 if ($this->data === false || substr($this->data, 0, self::SHORT_SIZE) !== self::JPEG_HEADER)
074 {
075 return;
076 }
077
078 // Look through file for SOF marker
079 $size = $this->getSizeInfo();
080
081 $this->fastImageSize->setSize($size);
082 $this->fastImageSize->setImageType(IMAGETYPE_JPEG);
083 }
084
085 /**
086 * Return if current data point is an SOF marker
087 *
088 * @param string $firstByte First byte to check
089 * @param string $secondByte Second byte to check
090 *
091 * @return bool True if current data point is SOF marker, false if not
092 */
093 protected function isSofMarker($firstByte, $secondByte)
094 {
095 return $firstByte === self::SOF_START_MARKER && in_array($secondByte, $this->sofMarkers);
096 }
097
098 /**
099 * Return if current data point is an APP marker
100 *
101 * @param string $firstByte First byte to check
102 * @param string $secondByte Second byte to check
103 *
104 * @return bool True if current data point is APP marker, false if not
105 */
106 protected function isAppMarker($firstByte, $secondByte)
107 {
108 return $firstByte === self::SOF_START_MARKER && in_array($secondByte, $this->appMarkers);
109 }
110
111 /**
112 * Return if current data point is a valid APP1 marker (EXIF or XMP)
113 *
114 * @param string $firstByte First byte to check
115 * @param string $secondByte Second byte to check
116 *
117 * @return bool True if current data point is valid APP1 marker, false if not
118 */
119 protected function isApp1Marker($firstByte, $secondByte)
120 {
121 return (!$this->foundExif || !$this->foundXmp) && $firstByte === self::SOF_START_MARKER && $secondByte === $this->appMarkers[1];
122 }
123
124 /**
125 * Get size info from image data
126 *
127 * @return array An array with the image's size info or an empty array if
128 * size info couldn't be found
129 */
130 protected function getSizeInfo()
131 {
132 $size = array();
133 // since we check $i + 1 we need to stop one step earlier
134 $dataLength = strlen($this->data) - 1;
135 $this->foundExif = $this->foundXmp = false;
136
137 // Look through file for SOF marker
138 for ($i = 0; $i < $dataLength; $i++)
139 {
140 // Only look for EXIF and XMP app marker once, other types more often
141 if (!$this->checkForAppMarker($dataLength, $i))
142 {
143 break;
144 }
145
146 if ($this->isSofMarker($this->data[$i], $this->data[$i + 1]))
147 {
148 // Extract size info from SOF marker
149 list(, $unpacked) = unpack("H*", substr($this->data, $i + self::LONG_SIZE + 1, self::LONG_SIZE));
150
151 // Get width and height from unpacked size info
152 $size = array(
153 'width' => hexdec(substr($unpacked, 4, 4)),
154 'height' => hexdec(substr($unpacked, 0, 4)),
155 );
156
157 break;
158 }
159 }
160
161 return $size;
162 }
163
164 /**
165 * Check for APP marker in data
166 *
167 * @param int $dataLength Length of input data
168 * @param int $index Current data index
169 *
170 * @return bool True if searching through data should be continued, false if not
171 */
172 protected function checkForAppMarker($dataLength, &$index)
173 {
174 if ($this->isApp1Marker($this->data[$index], $this->data[$index + 1]) || $this->isAppMarker($this->data[$index], $this->data[$index + 1]))
175 {
176 // Extract length from APP marker
177 list(, $unpacked) = unpack("H*", substr($this->data, $index + self::SHORT_SIZE, 2));
178
179 $length = hexdec(substr($unpacked, 0, 4));
180
181 $this->setApp1Flags($this->data[$index + 1]);
182
183 // Skip over length of APP header
184 $index += (int) $length;
185
186 // Make sure we don't exceed the data length
187 if ($index >= $dataLength)
188 {
189 return false;
190 }
191 }
192
193 return true;
194 }
195
196 /**
197 * Set APP1 flags for specified data point
198 *
199 * @param string $data Data point
200 */
201 protected function setApp1Flags($data)
202 {
203 if (!$this->foundExif)
204 {
205 $this->foundExif = $data === $this->appMarkers[1];
206 }
207 else if (!$this->foundXmp)
208 {
209 $this->foundXmp = $data === $this->appMarkers[1];
210 }
211 }
212 }
213