4 * PEL: PHP Exif Library.
5 * A library with support for reading and
6 * writing all Exif headers in JPEG and TIFF images using PHP.
8 * Copyright (C) 2004, 2005 Martin Geisler.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program in the file COPYING; if not, write to the
22 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
23 * Boston, MA 02110-1301 USA
25 namespace lsolesen\pel;
28 * Routines for converting back and forth between bytes and integers.
30 * @author Martin Geisler <mgeisler@users.sourceforge.net>
31 * @license http://www.gnu.org/licenses/gpl.html GNU General Public
37 * Conversion functions to and from bytes and integers.
39 * The functions found in this class are used to convert bytes into
40 * integers of several sizes ({@link bytesToShort}, {@link
41 * bytesToLong}, and {@link bytesToRational}) and convert integers of
42 * several sizes into bytes ({@link shortToBytes} and {@link
45 * All the methods are static and they all rely on an argument that
46 * specifies the byte order to be used, this must be one of the class
47 * constants {@link LITTLE_ENDIAN} or {@link BIG_ENDIAN}. These
48 * constants will be referred to as the pseudo type PelByteOrder
49 * throughout the documentation.
51 * @author Martin Geisler <mgeisler@users.sourceforge.net>
58 * Little-endian (Intel) byte order.
60 * Data stored in little-endian byte order store the least
61 * significant byte first, so the number 0x12345678 becomes 0x78
62 * 0x56 0x34 0x12 when stored with little-endian byte order.
64 const LITTLE_ENDIAN = true;
67 * Big-endian (Motorola) byte order.
69 * Data stored in big-endian byte order store the most significant
70 * byte first, so the number 0x12345678 becomes 0x12 0x34 0x56 0x78
71 * when stored with big-endian byte order.
73 const BIG_ENDIAN = false;
76 * Convert an unsigned short into two bytes.
78 * @param integer $value
79 * the unsigned short that will be converted. The lower
80 * two bytes will be extracted regardless of the actual size passed.
82 * @param integer $endian
83 * one of {@link LITTLE_ENDIAN} and {@link
86 * @return string the bytes representing the unsigned short.
88 public static function shortToBytes($value, $endian)
90 if ($endian == self::LITTLE_ENDIAN) {
91 return chr($value) . chr($value >> 8);
93 return chr($value >> 8) . chr($value);
98 * Convert a signed short into two bytes.
100 * @param integer $value
101 * the signed short that will be converted. The lower
102 * two bytes will be extracted regardless of the actual size passed.
104 * @param integer $endian
105 * one of {@link LITTLE_ENDIAN} and {@link
108 * @return string the bytes representing the signed short.
110 public static function sShortToBytes($value, $endian)
113 * We can just use shortToBytes, since signed shorts fits well
114 * within the 32 bit signed integers used in PHP.
116 return self::shortToBytes($value, $endian);
120 * Convert an unsigned long into four bytes.
122 * Because PHP limits the size of integers to 32 bit signed, one
123 * cannot really have an unsigned integer in PHP. But integers
124 * larger than 2^31-1 will be promoted to 64 bit signed floating
125 * point numbers, and so such large numbers can be handled too.
127 * @param integer $value
128 * the unsigned long that will be converted. The
129 * argument will be treated as an unsigned 32 bit integer and the
130 * lower four bytes will be extracted. Treating the argument as an
131 * unsigned integer means that the absolute value will be used. Use
132 * {@link sLongToBytes} to convert signed integers.
134 * @param integer $endian
135 * one of {@link LITTLE_ENDIAN} and {@link
138 * @return string the bytes representing the unsigned long.
140 public static function longToBytes($value, $endian)
143 * We cannot convert the number to bytes in the normal way (using
144 * shifts and modulo calculations) because the PHP operator >> and
145 * function chr() clip their arguments to 2^31-1, which is the
146 * largest signed integer known to PHP. But luckily base_convert
147 * handles such big numbers.
149 $hex = str_pad(base_convert($value, 10, 16), 8, '0', STR_PAD_LEFT);
150 if ($endian == self::LITTLE_ENDIAN) {
151 return (chr(hexdec($hex{6} . $hex{7})) . chr(hexdec($hex{4} . $hex{5})) . chr(hexdec($hex{2} . $hex{3})) .
152 chr(hexdec($hex{0} . $hex{1})));
154 return (chr(hexdec($hex{0} . $hex{1})) . chr(hexdec($hex{2} . $hex{3})) . chr(hexdec($hex{4} . $hex{5})) .
155 chr(hexdec($hex{6} . $hex{7})));
160 * Convert a signed long into four bytes.
162 * @param integer $value
163 * the signed long that will be converted. The argument
164 * will be treated as a signed 32 bit integer, from which the lower
165 * four bytes will be extracted.
167 * @param integer $endian
168 * one of {@link LITTLE_ENDIAN} and {@link
171 * @return string the bytes representing the signed long.
173 public static function sLongToBytes($value, $endian)
176 * We can convert the number into bytes in the normal way using
177 * shifts and modulo calculations here (in contrast with
178 * longToBytes) because PHP automatically handles 32 bit signed
181 if ($endian == self::LITTLE_ENDIAN) {
182 return (chr($value) . chr($value >> 8) . chr($value >> 16) . chr($value >> 24));
184 return (chr($value >> 24) . chr($value >> 16) . chr($value >> 8) . chr($value));
189 * Extract an unsigned byte from a string of bytes.
191 * @param string $bytes
194 * @param integer $offset
195 * The byte found at the offset will be
196 * returned as an integer. The must be at least one byte available
199 * @return integer $offset the unsigned byte found at offset, e.g., an integer
200 * in the range 0 to 255.
202 public static function bytesToByte($bytes, $offset)
204 return ord($bytes{$offset});
208 * Extract a signed byte from bytes.
210 * @param string $bytes
213 * @param integer $offset
214 * the offset. The byte found at the offset will be
215 * returned as an integer. The must be at least one byte available
218 * @return integer the signed byte found at offset, e.g., an integer in
219 * the range -128 to 127.
221 public static function bytesToSByte($bytes, $offset)
223 $n = self::bytesToByte($bytes, $offset);
232 * Extract an unsigned short from bytes.
234 * @param string $bytes
237 * @param integer $offset
238 * the offset. The short found at the offset will be
239 * returned as an integer. There must be at least two bytes
240 * available beginning at the offset given.
241 * @param integer $endian
242 * one of {@link LITTLE_ENDIAN} and {@link
244 * @return integer the unsigned short found at offset, e.g., an integer
245 * in the range 0 to 65535.
248 public static function bytesToShort($bytes, $offset, $endian)
250 if ($endian == self::LITTLE_ENDIAN) {
251 return (ord($bytes{$offset + 1}) * 256 + ord($bytes{$offset}));
253 return (ord($bytes{$offset}) * 256 + ord($bytes{$offset + 1}));
258 * Extract a signed short from bytes.
260 * @param string $bytes
262 * @param integer $offset
263 * The short found at offset will be returned
264 * as an integer. There must be at least two bytes available
265 * beginning at the offset given.
266 * @param integer $endian
267 * one of {@link LITTLE_ENDIAN} and {@link
269 * @return integer the signed byte found at offset, e.g., an integer in
270 * the range -32768 to 32767.
273 public static function bytesToSShort($bytes, $offset, $endian)
275 $n = self::bytesToShort($bytes, $offset, $endian);
284 * Extract an unsigned long from bytes.
286 * @param string $bytes
288 * @param integer $offset
289 * The long found at offset will be returned
290 * as an integer. There must be at least four bytes available
291 * beginning at the offset given.
292 * @param integer $endian
293 * one of {@link LITTLE_ENDIAN} and {@link
295 * @return integer the unsigned long found at offset, e.g., an integer
296 * in the range 0 to 4294967295.
299 public static function bytesToLong($bytes, $offset, $endian)
301 if ($endian == self::LITTLE_ENDIAN) {
302 return (ord($bytes{$offset + 3}) * 16777216 + ord($bytes{$offset + 2}) * 65536 +
303 ord($bytes{$offset + 1}) * 256 + ord($bytes{$offset}));
305 return (ord($bytes{$offset}) * 16777216 + ord($bytes{$offset + 1}) * 65536 + ord($bytes{$offset + 2}) * 256 +
306 ord($bytes{$offset + 3}));
311 * Extract a signed long from bytes.
313 * @param string $bytes
315 * @param integer $offset
316 * The long found at offset will be returned
317 * as an integer. There must be at least four bytes available
318 * beginning at the offset given.
319 * @param integer $endian
320 * one of {@link LITTLE_ENDIAN} and {@link
322 * @return integer the signed long found at offset, e.g., an integer in
323 * the range -2147483648 to 2147483647.
326 public static function bytesToSLong($bytes, $offset, $endian)
328 $n = self::bytesToLong($bytes, $offset, $endian);
329 if ($n > 2147483647) {
330 return $n - 4294967296;
337 * Extract an unsigned rational from bytes.
339 * @param string $bytes
341 * @param integer $offset
342 * The rational found at offset will be
343 * returned as an array. There must be at least eight bytes
344 * available beginning at the offset given.
345 * @param integer $endian
346 * one of {@link LITTLE_ENDIAN} and {@link
348 * @return array the unsigned rational found at offset, e.g., an
349 * array with two integers in the range 0 to 4294967295.
352 public static function bytesToRational($bytes, $offset, $endian)
355 self::bytesToLong($bytes, $offset, $endian),
356 self::bytesToLong($bytes, $offset + 4, $endian)
361 * Extract a signed rational from bytes.
363 * @param string $bytes
365 * @param integer $offset
366 * The rational found at offset will be
367 * returned as an array. There must be at least eight bytes
368 * available beginning at the offset given.
369 * @param integer $endian
370 * one of {@link LITTLE_ENDIAN} and {@link
372 * @return array the signed rational found at offset, e.g., an array
373 * with two integers in the range -2147483648 to 2147483647.
376 public static function bytesToSRational($bytes, $offset, $endian)
379 self::bytesToSLong($bytes, $offset, $endian),
380 self::bytesToSLong($bytes, $offset + 4, $endian)
385 * Format bytes for dumping.
387 * This method is for debug output, it will format a string as a
388 * hexadecimal dump suitable for display on a terminal. The output
389 * is printed directly to standard out.
391 * @param string $bytes
392 * the bytes that will be dumped.
394 * @param integer $max
395 * the maximum number of bytes to dump. If this is left
396 * out (or left to the default of 0), then the entire string will be
400 public static function bytesToDump($bytes, $max = 0)
409 for ($i = 0; $i < $s; $i ++) {
410 printf('%02X ', ord($bytes{$i}));
412 if (($i + 1) % $line == 0) {