Source for file PelConvert.php

Documentation is available at PelConvert.php

  1. <?php
  2.  
  3. /*  PEL: PHP Exif Library.  A library with support for reading and
  4.  *  writing all Exif headers in JPEG and TIFF images using PHP.
  5.  *
  6.  *  Copyright (C) 2004, 2005  Martin Geisler.
  7.  *
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program in the file COPYING; if not, write to the
  20.  *  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  21.  *  Boston, MA 02110-1301 USA
  22.  */
  23.  
  24. /* $Id$ */
  25.  
  26.  
  27. /**
  28.  * Routines for converting back and forth between bytes and integers.
  29.  *
  30.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  31.  * @version $Revision$
  32.  * @date $Date$
  33.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public
  34.  *  License (GPL)
  35.  * @package PEL
  36.  */
  37.  
  38. /**
  39.  * Conversion functions to and from bytes and integers.
  40.  *
  41.  * The functions found in this class are used to convert bytes into
  42.  * integers of several sizes ({@link bytesToShort}{@link }
  43.  * bytesToLong}, and {@link bytesToRational}) and convert integers of
  44.  * several sizes into bytes ({@link shortToBytes} and {@link }
  45.  * longToBytes}).
  46.  *
  47.  * All the methods are static and they all rely on an argument that
  48.  * specifies the byte order to be used, this must be one of the class
  49.  * constants {@link LITTLE_ENDIAN} or {@link BIG_ENDIAN}.  These
  50.  * constants will be referred to as the pseudo type PelByteOrder
  51.  * throughout the documentation.
  52.  *
  53.  * @author Martin Geisler <mgeisler@users.sourceforge.net>
  54.  * @package PEL
  55.  */
  56. class PelConvert {
  57.  
  58.   /**
  59.    * Little-endian (Intel) byte order.
  60.    *
  61.    * Data stored in little-endian byte order store the least
  62.    * significant byte first, so the number 0x12345678 becomes 0x78
  63.    * 0x56 0x34 0x12 when stored with little-endian byte order.
  64.    */
  65.   const LITTLE_ENDIAN true;
  66.  
  67.   /**
  68.    * Big-endian (Motorola) byte order.
  69.    *
  70.    * Data stored in big-endian byte order store the most significant
  71.    * byte first, so the number 0x12345678 becomes 0x12 0x34 0x56 0x78
  72.    * when stored with big-endian byte order.
  73.    */
  74.   const BIG_ENDIAN false;
  75.  
  76.  
  77.   /**
  78.    * Convert an unsigned short into two bytes.
  79.    *
  80.    * @param int the unsigned short that will be converted.  The lower
  81.    *  two bytes will be extracted regardless of the actual size passed.
  82.    *
  83.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  84.    *  BIG_ENDIAN}.
  85.    *
  86.    * @return string the bytes representing the unsigned short.
  87.    */
  88.   static function shortToBytes($value$endian{
  89.     if ($endian == self::LITTLE_ENDIAN)
  90.       return chr($valuechr($value >> 8);
  91.     else
  92.       return chr($value >> 8chr($value);
  93.   }
  94.  
  95.  
  96.   /**
  97.    * Convert a signed short into two bytes.
  98.    *
  99.    * @param int the signed short that will be converted.  The lower
  100.    *  two bytes will be extracted regardless of the actual size passed.
  101.    *
  102.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  103.    *  BIG_ENDIAN}.
  104.    *
  105.    * @return string the bytes representing the signed short.
  106.    */
  107.   static function sShortToBytes($value$endian{
  108.     /* We can just use shortToBytes, since signed shorts fits well
  109.      * within the 32 bit signed integers used in PHP. */
  110.     return self::shortToBytes($value$endian);
  111.   }
  112.   
  113.  
  114.   /**
  115.    * Convert an unsigned long into four bytes.
  116.    *
  117.    * Because PHP limits the size of integers to 32 bit signed, one
  118.    * cannot really have an unsigned integer in PHP.  But integers
  119.    * larger than 2^31-1 will be promoted to 64 bit signed floating
  120.    * point numbers, and so such large numbers can be handled too.
  121.    *
  122.    * @param int the unsigned long that will be converted.  The
  123.    *  argument will be treated as an unsigned 32 bit integer and the
  124.    *  lower four bytes will be extracted.  Treating the argument as an
  125.    *  unsigned integer means that the absolute value will be used.  Use
  126.    *  {@link sLongToBytes} to convert signed integers.
  127.    *
  128.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  129.    *  BIG_ENDIAN}.
  130.    *
  131.    * @return string the bytes representing the unsigned long.
  132.    */
  133.   static function longToBytes($value$endian{
  134.     /* We cannot convert the number to bytes in the normal way (using
  135.      * shifts and modulo calculations) because the PHP operator >> and
  136.      * function chr() clip their arguments to 2^31-1, which is the
  137.      * largest signed integer known to PHP.  But luckily base_convert
  138.      * handles such big numbers. */
  139.     $hex str_pad(base_convert($value1016)8'0'STR_PAD_LEFT);
  140.     if ($endian == self::LITTLE_ENDIAN)
  141.       return (chr(hexdec($hex{6$hex{7})) .
  142.               chr(hexdec($hex{4$hex{5})) .
  143.               chr(hexdec($hex{2$hex{3})) .
  144.               chr(hexdec($hex{0$hex{1})));
  145.     else
  146.       return (chr(hexdec($hex{0$hex{1})) .
  147.               chr(hexdec($hex{2$hex{3})) .
  148.               chr(hexdec($hex{4$hex{5})) .
  149.               chr(hexdec($hex{6$hex{7})));
  150.   }
  151.  
  152.  
  153.   /**
  154.    * Convert a signed long into four bytes.
  155.    *
  156.    * @param int the signed long that will be converted.  The argument
  157.    *  will be treated as a signed 32 bit integer, from which the lower
  158.    *  four bytes will be extracted.
  159.    *
  160.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  161.    *  BIG_ENDIAN}.
  162.    *
  163.    * @return string the bytes representing the signed long.
  164.    */
  165.   static function sLongToBytes($value$endian{
  166.     /* We can convert the number into bytes in the normal way using
  167.      * shifts and modulo calculations here (in contrast with
  168.      * longToBytes) because PHP automatically handles 32 bit signed
  169.      * integers for us. */
  170.     if ($endian == self::LITTLE_ENDIAN)
  171.       return (chr($value.
  172.               chr($value >>  8.
  173.               chr($value >> 16.
  174.               chr($value >> 24));
  175.     else
  176.       return (chr($value >> 24.
  177.               chr($value >> 16.
  178.               chr($value >>  8.
  179.               chr($value));
  180.   }
  181.  
  182.  
  183.   /**
  184.    * Extract an unsigned byte from a string of bytes.
  185.    *
  186.    * @param string the bytes.
  187.    *
  188.    * @param int the offset.  The byte found at the offset will be
  189.    *  returned as an integer.  The must be at least one byte available
  190.    *  at offset.
  191.    *
  192.    * @return int the unsigned byte found at offset, e.g., an integer
  193.    *  in the range 0 to 255.
  194.    */
  195.   static function bytesToByte($bytes$offset{
  196.     return ord($bytes{$offset});
  197.   }
  198.  
  199.  
  200.   /**
  201.    * Extract a signed byte from bytes.
  202.    *
  203.    * @param string the bytes.
  204.    *
  205.    * @param int the offset.  The byte found at the offset will be
  206.    *  returned as an integer.  The must be at least one byte available
  207.    *  at offset.
  208.    *
  209.    * @return int the signed byte found at offset, e.g., an integer in
  210.    *  the range -128 to 127.
  211.    */
  212.   static function bytesToSByte($bytes$offset{
  213.     $n self::bytesToByte($bytes$offset);
  214.     if ($n 127)
  215.       return $n 256;
  216.     else
  217.       return $n;
  218.   }
  219.  
  220.  
  221.   /**
  222.    * Extract an unsigned short from bytes.
  223.    *
  224.    * @param string the bytes.
  225.    *
  226.    * @param int the offset.  The short found at the offset will be
  227.    *  returned as an integer.  There must be at least two bytes
  228.    *  available beginning at the offset given.
  229.    *
  230.    * @return int the unsigned short found at offset, e.g., an integer
  231.    *  in the range 0 to 65535.
  232.    *
  233.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  234.    *  BIG_ENDIAN}.
  235.    */
  236.   static function bytesToShort($bytes$offset$endian{
  237.     if ($endian == self::LITTLE_ENDIAN)
  238.       return (ord($bytes{$offset+1}256 +
  239.               ord($bytes{$offset}));
  240.     else
  241.       return (ord($bytes{$offset})   256 +
  242.               ord($bytes{$offset+1}));
  243.   }
  244.  
  245.  
  246.   /**
  247.    * Extract a signed short from bytes.
  248.    *
  249.    * @param string the bytes.
  250.    *
  251.    * @param int the offset.  The short found at offset will be returned
  252.    *  as an integer.  There must be at least two bytes available
  253.    *  beginning at the offset given.
  254.    *
  255.    * @return int the signed byte found at offset, e.g., an integer in
  256.    *  the range -32768 to 32767.
  257.    *
  258.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  259.    *  BIG_ENDIAN}.
  260.    */
  261.   static function bytesToSShort($bytes$offset$endian{
  262.     $n self::bytesToShort($bytes$offset$endian);
  263.     if ($n 32767)
  264.       return $n 65536;
  265.     else
  266.       return $n;
  267.   }
  268.  
  269.  
  270.   /**
  271.    * Extract an unsigned long from bytes.
  272.    *
  273.    * @param string the bytes.
  274.    *
  275.    * @param int the offset.  The long found at offset will be returned
  276.    *  as an integer.  There must be at least four bytes available
  277.    *  beginning at the offset given.
  278.    *
  279.    * @return int the unsigned long found at offset, e.g., an integer
  280.    *  in the range 0 to 4294967295.
  281.    *
  282.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  283.    *  BIG_ENDIAN}.
  284.    */
  285.   static function bytesToLong($bytes$offset$endian{
  286.     if ($endian == self::LITTLE_ENDIAN)
  287.       return (ord($bytes{$offset+3}16777216 +
  288.               ord($bytes{$offset+2}65536    +
  289.               ord($bytes{$offset+1}256      +
  290.               ord($bytes{$offset}));
  291.     else
  292.       return (ord($bytes{$offset})   16777216 +
  293.               ord($bytes{$offset+1}65536    +
  294.               ord($bytes{$offset+2}256      +
  295.               ord($bytes{$offset+3}));
  296.   }
  297.  
  298.  
  299.   /**
  300.    * Extract a signed long from bytes.
  301.    *
  302.    * @param string the bytes.
  303.    *
  304.    * @param int the offset.  The long found at offset will be returned
  305.    *  as an integer.  There must be at least four bytes available
  306.    *  beginning at the offset given.
  307.    *
  308.    * @return int the signed long found at offset, e.g., an integer in
  309.    *  the range -2147483648 to 2147483647.
  310.    *
  311.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  312.    *  BIG_ENDIAN}.
  313.    */
  314.   static function bytesToSLong($bytes$offset$endian{
  315.     $n self::bytesToLong($bytes$offset$endian);
  316.     if ($n 2147483647)
  317.       return $n 4294967296;
  318.     else
  319.       return $n;
  320.   }
  321.  
  322.  
  323.   /**
  324.    * Extract an unsigned rational from bytes.
  325.    *
  326.    * @param string the bytes.
  327.    *
  328.    * @param int the offset.  The rational found at offset will be
  329.    *  returned as an array.  There must be at least eight bytes
  330.    *  available beginning at the offset given.
  331.    *
  332.    * @return array the unsigned rational found at offset, e.g., an
  333.    *  array with two integers in the range 0 to 4294967295.
  334.    *
  335.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  336.    *  BIG_ENDIAN}.
  337.    */
  338.   static function bytesToRational($bytes$offset$endian{
  339.     return array(self::bytesToLong($bytes$offset$endian),
  340.                  self::bytesToLong($bytes$offset+4$endian));
  341.   }
  342.  
  343.  
  344.   /**
  345.    * Extract a signed rational from bytes.
  346.    *
  347.    * @param string the bytes.
  348.    *
  349.    * @param int the offset.  The rational found at offset will be
  350.    *  returned as an array.  There must be at least eight bytes
  351.    *  available beginning at the offset given.
  352.    *
  353.    * @return array the signed rational found at offset, e.g., an array
  354.    *  with two integers in the range -2147483648 to 2147483647.
  355.    *
  356.    * @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link }
  357.    *  BIG_ENDIAN}.
  358.    */
  359.   static function bytesToSRational($bytes$offset$endian{
  360.     return array(self::bytesToSLong($bytes$offset$endian),
  361.                  self::bytesToSLong($bytes$offset+4$endian));
  362.   }
  363.  
  364.  
  365.   /**
  366.    * Format bytes for dumping.
  367.    *
  368.    * This method is for debug output, it will format a string as a
  369.    * hexadecimal dump suitable for display on a terminal.  The output
  370.    * is printed directly to standard out.
  371.    *
  372.    * @param string the bytes that will be dumped.
  373.    *
  374.    * @param int the maximum number of bytes to dump.  If this is left
  375.    *  out (or left to the default of 0), then the entire string will be
  376.    *  dumped.
  377.    */
  378.   static function bytesToDump($bytes$max 0{
  379.     $s strlen($bytes);
  380.  
  381.     if ($max 0)
  382.       $s min($max$s);
  383.  
  384.     $line 24;
  385.  
  386.     for ($i 0$i $s$i++{
  387.       printf('%02X 'ord($bytes{$i}));
  388.       
  389.       if (($i+1$line == 0)
  390.         print("\n");
  391.     }
  392.     print("\n");
  393.   }
  394.  
  395. }
  396.  
  397. ?>

Documentation generated on Thu, 05 May 2011 07:18:57 +0200 by phpDocumentor 1.4.3