PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_jce/editor/tiny_mce/plugins/imgmanager_ext/classes/pel/PelConvert.php

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