PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/administrator/components/com_virtuemart/classes/pdf/gif.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 1105 lines | 806 code | 188 blank | 111 comment | 136 complexity | 4ac981ecc90ea8372c5d458daf0c33d9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. *
  5. * @version $Id: gif.php 1306 2008-03-08 16:31:44Z gregdev $
  6. * @package VirtueMart
  7. * @subpackage HTML2PDF
  8. * @copyright Copyright (C) 2004-2007 soeren - All rights reserved.
  9. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  10. * VirtueMart is free software. This version may have been modified pursuant
  11. * to the GNU General Public License, and as distributed it includes or
  12. * is derivative of works licensed under the GNU General Public License or
  13. * other free or open source software licenses.
  14. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  15. *
  16. * http://virtuemart.net
  17. */
  18. ///////////////////////////////////////////////////////////////////////////////////////////////////
  19. // GIF Util - (C) 2003 Yamasoft (S/C)
  20. // http://www.yamasoft.com
  21. // All Rights Reserved
  22. // This file can be frelly copied, distributed, modified, updated by anyone under the only
  23. // condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
  24. ///////////////////////////////////////////////////////////////////////////////////////////////////
  25. // <gif> = gif_loadFile(filename, [index])
  26. // <bool> = gif_getSize(<gif> or filename, &width, &height)
  27. // <bool> = gif_outputAsPng(<gif>, filename, [bgColor])
  28. // <bool> = gif_outputAsBmp(<gif>, filename, [bgcolor])
  29. // <bool> = gif_outputAsJpeg(<gif>, filename, [bgcolor]) - Requires cjpeg
  30. ///////////////////////////////////////////////////////////////////////////////////////////////////
  31. ///////////////////////////////////////////////////////////////////////////////////////////////////
  32. function gif_loadFile($lpszFileName, $iIndex = 0)
  33. {
  34. $gif = new CGIF();
  35. if(!$gif->loadFile($lpszFileName, $iIndex)) {
  36. return false;
  37. }
  38. return $gif;
  39. }
  40. ///////////////////////////////////////////////////////////////////////////////////////////////////
  41. function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1)
  42. {
  43. if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) {
  44. return false;
  45. }
  46. $fd = $gif->getBmp($bgColor);
  47. if(strlen($fd) <= 0) {
  48. return false;
  49. }
  50. if(!($fh = @fOpen($lpszFileName, "wb"))) {
  51. return false;
  52. }
  53. @fWrite($fh, $fd, strlen($fd));
  54. @fFlush($fh);
  55. @fClose($fh);
  56. return true;
  57. }
  58. ///////////////////////////////////////////////////////////////////////////////////////////////////
  59. function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1)
  60. {
  61. if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) {
  62. return false;
  63. }
  64. $fd = $gif->getPng($bgColor);
  65. if(strlen($fd) <= 0) {
  66. return false;
  67. }
  68. if(!($fh = @fOpen($lpszFileName, "wb"))) {
  69. return false;
  70. }
  71. @fWrite($fh, $fd, strlen($fd));
  72. @fFlush($fh);
  73. @fClose($fh);
  74. return true;
  75. }
  76. ///////////////////////////////////////////////////////////////////////////////////////////////////
  77. function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1)
  78. {
  79. if(gif_outputAsBmp($gif, "$lpszFileName.bmp", $gbColor)) {
  80. exec("cjpeg $lpszFileName.bmp >$lpszFileName 2>/dev/null");
  81. @unLink("$lpszFileName.bmp");
  82. if(@file_exists($lpszFileName)) {
  83. if(@fileSize($lpszFileName) > 0) {
  84. return true;
  85. }
  86. @unLink($lpszFileName);
  87. }
  88. }
  89. return false;
  90. }
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////
  92. function gif_getSize($gif, &$width, &$height)
  93. {
  94. if(isSet($gif) && (@get_class($gif) == "cgif") && $gif->loaded()) {
  95. $width = $gif->width();
  96. $height = $gif->height();
  97. }
  98. else if(@file_exists($gif)) {
  99. $myGIF = new CGIF();
  100. if(!$myGIF->getSize($gif, $width, $height)) {
  101. return false;
  102. }
  103. }
  104. else {
  105. return false;
  106. }
  107. return true;
  108. }
  109. ///////////////////////////////////////////////////////////////////////////////////////////////////
  110. class CGIFLZW
  111. {
  112. var $MAX_LZW_BITS;
  113. var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
  114. var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
  115. ///////////////////////////////////////////////////////////////////////////
  116. // CONSTRUCTOR
  117. function CGIFLZW()
  118. {
  119. $this->MAX_LZW_BITS = 12;
  120. unSet($this->Next);
  121. unSet($this->Vals);
  122. unSet($this->Stack);
  123. unSet($this->Buf);
  124. $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1);
  125. $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1);
  126. $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
  127. $this->Buf = range(0, 279);
  128. }
  129. ///////////////////////////////////////////////////////////////////////////
  130. function deCompress($data, &$datLen)
  131. {
  132. $stLen = strlen($data);
  133. $datLen = 0;
  134. $ret = "";
  135. // INITIALIZATION
  136. $this->LZWCommand($data, true);
  137. while(($iIndex = $this->LZWCommand($data, false)) >= 0) {
  138. $ret .= chr($iIndex);
  139. }
  140. $datLen = $stLen - strlen($data);
  141. if($iIndex != -2) {
  142. return false;
  143. }
  144. return $ret;
  145. }
  146. ///////////////////////////////////////////////////////////////////////////
  147. function LZWCommand(&$data, $bInit)
  148. {
  149. if($bInit) {
  150. $this->SetCodeSize = ord($data{0});
  151. $data = substr($data, 1);
  152. $this->CodeSize = $this->SetCodeSize + 1;
  153. $this->ClearCode = 1 << $this->SetCodeSize;
  154. $this->EndCode = $this->ClearCode + 1;
  155. $this->MaxCode = $this->ClearCode + 2;
  156. $this->MaxCodeSize = $this->ClearCode << 1;
  157. $this->GetCode($data, $bInit);
  158. $this->Fresh = 1;
  159. for($i = 0; $i < $this->ClearCode; $i++) {
  160. $this->Next[$i] = 0;
  161. $this->Vals[$i] = $i;
  162. }
  163. for(; $i < (1 << $this->MAX_LZW_BITS); $i++) {
  164. $this->Next[$i] = 0;
  165. $this->Vals[$i] = 0;
  166. }
  167. $this->sp = 0;
  168. return 1;
  169. }
  170. if($this->Fresh) {
  171. $this->Fresh = 0;
  172. do {
  173. $this->FirstCode = $this->GetCode($data, $bInit);
  174. $this->OldCode = $this->FirstCode;
  175. }
  176. while($this->FirstCode == $this->ClearCode);
  177. return $this->FirstCode;
  178. }
  179. if($this->sp > 0) {
  180. $this->sp--;
  181. return $this->Stack[$this->sp];
  182. }
  183. while(($Code = $this->GetCode($data, $bInit)) >= 0) {
  184. if($Code == $this->ClearCode) {
  185. for($i = 0; $i < $this->ClearCode; $i++) {
  186. $this->Next[$i] = 0;
  187. $this->Vals[$i] = $i;
  188. }
  189. for(; $i < (1 << $this->MAX_LZW_BITS); $i++) {
  190. $this->Next[$i] = 0;
  191. $this->Vals[$i] = 0;
  192. }
  193. $this->CodeSize = $this->SetCodeSize + 1;
  194. $this->MaxCodeSize = $this->ClearCode << 1;
  195. $this->MaxCode = $this->ClearCode + 2;
  196. $this->sp = 0;
  197. $this->FirstCode = $this->GetCode($data, $bInit);
  198. $this->OldCode = $this->FirstCode;
  199. return $this->FirstCode;
  200. }
  201. if($Code == $this->EndCode) {
  202. return -2;
  203. }
  204. $InCode = $Code;
  205. if($Code >= $this->MaxCode) {
  206. $this->Stack[$this->sp] = $this->FirstCode;
  207. $this->sp++;
  208. $Code = $this->OldCode;
  209. }
  210. while($Code >= $this->ClearCode) {
  211. $this->Stack[$this->sp] = $this->Vals[$Code];
  212. $this->sp++;
  213. if($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
  214. return -1;
  215. $Code = $this->Next[$Code];
  216. }
  217. $this->FirstCode = $this->Vals[$Code];
  218. $this->Stack[$this->sp] = $this->FirstCode;
  219. $this->sp++;
  220. if(($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
  221. $this->Next[$Code] = $this->OldCode;
  222. $this->Vals[$Code] = $this->FirstCode;
  223. $this->MaxCode++;
  224. if(($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
  225. $this->MaxCodeSize *= 2;
  226. $this->CodeSize++;
  227. }
  228. }
  229. $this->OldCode = $InCode;
  230. if($this->sp > 0) {
  231. $this->sp--;
  232. return $this->Stack[$this->sp];
  233. }
  234. }
  235. return $Code;
  236. }
  237. ///////////////////////////////////////////////////////////////////////////
  238. function GetCode(&$data, $bInit)
  239. {
  240. if($bInit) {
  241. $this->CurBit = 0;
  242. $this->LastBit = 0;
  243. $this->Done = 0;
  244. $this->LastByte = 2;
  245. return 1;
  246. }
  247. if(($this->CurBit + $this->CodeSize) >= $this->LastBit) {
  248. if($this->Done) {
  249. if($this->CurBit >= $this->LastBit) {
  250. // Ran off the end of my bits
  251. return 0;
  252. }
  253. return -1;
  254. }
  255. $this->Buf[0] = $this->Buf[$this->LastByte - 2];
  256. $this->Buf[1] = $this->Buf[$this->LastByte - 1];
  257. $Count = ord($data{0});
  258. $data = substr($data, 1);
  259. if($Count) {
  260. for($i = 0; $i < $Count; $i++) {
  261. $this->Buf[2 + $i] = ord($data{$i});
  262. }
  263. $data = substr($data, $Count);
  264. }
  265. else {
  266. $this->Done = 1;
  267. }
  268. $this->LastByte = 2 + $Count;
  269. $this->CurBit = ($this->CurBit - $this->LastBit) + 16;
  270. $this->LastBit = (2 + $Count) << 3;
  271. }
  272. $iRet = 0;
  273. for($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
  274. $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j;
  275. }
  276. $this->CurBit += $this->CodeSize;
  277. return $iRet;
  278. }
  279. }
  280. ///////////////////////////////////////////////////////////////////////////////////////////////////
  281. class CGIFCOLORTABLE
  282. {
  283. var $m_nColors;
  284. var $m_arColors;
  285. ///////////////////////////////////////////////////////////////////////////
  286. // CONSTRUCTOR
  287. function CGIFCOLORTABLE()
  288. {
  289. unSet($this->m_nColors);
  290. unSet($this->m_arColors);
  291. }
  292. ///////////////////////////////////////////////////////////////////////////
  293. function load($lpData, $num)
  294. {
  295. $this->m_nColors = 0;
  296. $this->m_arColors = array();
  297. for($i = 0; $i < $num; $i++) {
  298. $rgb = substr($lpData, $i * 3, 3);
  299. if(strlen($rgb) < 3) {
  300. return false;
  301. }
  302. $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0});
  303. $this->m_nColors++;
  304. }
  305. return true;
  306. }
  307. ///////////////////////////////////////////////////////////////////////////
  308. function toString()
  309. {
  310. $ret = "";
  311. for($i = 0; $i < $this->m_nColors; $i++) {
  312. $ret .=
  313. chr(($this->m_arColors[$i] & 0x000000FF)) . // R
  314. chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
  315. chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
  316. }
  317. return $ret;
  318. }
  319. ///////////////////////////////////////////////////////////////////////////
  320. function toRGBQuad()
  321. {
  322. $ret = "";
  323. for($i = 0; $i < $this->m_nColors; $i++) {
  324. $ret .=
  325. chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
  326. chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
  327. chr(($this->m_arColors[$i] & 0x000000FF)) . // R
  328. "\x00";
  329. }
  330. return $ret;
  331. }
  332. ///////////////////////////////////////////////////////////////////////////
  333. function colorIndex($rgb)
  334. {
  335. $rgb = intval($rgb) & 0xFFFFFF;
  336. $r1 = ($rgb & 0x0000FF);
  337. $g1 = ($rgb & 0x00FF00) >> 8;
  338. $b1 = ($rgb & 0xFF0000) >> 16;
  339. $idx = -1;
  340. for($i = 0; $i < $this->m_nColors; $i++) {
  341. $r2 = ($this->m_arColors[$i] & 0x000000FF);
  342. $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
  343. $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
  344. $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
  345. if(($idx == -1) || ($d < $dif)) {
  346. $idx = $i;
  347. $dif = $d;
  348. }
  349. }
  350. return $idx;
  351. }
  352. }
  353. ///////////////////////////////////////////////////////////////////////////////////////////////////
  354. class CGIFFILEHEADER
  355. {
  356. var $m_lpVer;
  357. var $m_nWidth;
  358. var $m_nHeight;
  359. var $m_bGlobalClr;
  360. var $m_nColorRes;
  361. var $m_bSorted;
  362. var $m_nTableSize;
  363. var $m_nBgColor;
  364. var $m_nPixelRatio;
  365. var $m_colorTable;
  366. ///////////////////////////////////////////////////////////////////////////
  367. // CONSTRUCTOR
  368. function CGIFFILEHEADER()
  369. {
  370. unSet($this->m_lpVer);
  371. unSet($this->m_nWidth);
  372. unSet($this->m_nHeight);
  373. unSet($this->m_bGlobalClr);
  374. unSet($this->m_nColorRes);
  375. unSet($this->m_bSorted);
  376. unSet($this->m_nTableSize);
  377. unSet($this->m_nBgColor);
  378. unSet($this->m_nPixelRatio);
  379. unSet($this->m_colorTable);
  380. }
  381. ///////////////////////////////////////////////////////////////////////////
  382. function load($lpData, &$hdrLen)
  383. {
  384. $hdrLen = 0;
  385. $this->m_lpVer = substr($lpData, 0, 6);
  386. if(($this->m_lpVer <> "GIF87a") && ($this->m_lpVer <> "GIF89a")) {
  387. return false;
  388. }
  389. $this->m_nWidth = $this->w2i(substr($lpData, 6, 2));
  390. $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
  391. if(!$this->m_nWidth || !$this->m_nHeight) {
  392. return false;
  393. }
  394. $b = ord(substr($lpData, 10, 1));
  395. $this->m_bGlobalClr = ($b & 0x80) ? true : false;
  396. $this->m_nColorRes = ($b & 0x70) >> 4;
  397. $this->m_bSorted = ($b & 0x08) ? true : false;
  398. $this->m_nTableSize = 2 << ($b & 0x07);
  399. $this->m_nBgColor = ord(substr($lpData, 11, 1));
  400. $this->m_nPixelRatio = ord(substr($lpData, 12, 1));
  401. $hdrLen = 13;
  402. if($this->m_bGlobalClr) {
  403. $this->m_colorTable = new CGIFCOLORTABLE();
  404. if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
  405. return false;
  406. }
  407. $hdrLen += 3 * $this->m_nTableSize;
  408. }
  409. return true;
  410. }
  411. ///////////////////////////////////////////////////////////////////////////
  412. function w2i($str)
  413. {
  414. return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
  415. }
  416. }
  417. ///////////////////////////////////////////////////////////////////////////////////////////////////
  418. class CGIFIMAGEHEADER
  419. {
  420. var $m_nLeft;
  421. var $m_nTop;
  422. var $m_nWidth;
  423. var $m_nHeight;
  424. var $m_bLocalClr;
  425. var $m_bInterlace;
  426. var $m_bSorted;
  427. var $m_nTableSize;
  428. var $m_colorTable;
  429. ///////////////////////////////////////////////////////////////////////////
  430. // CONSTRUCTOR
  431. function CGIFIMAGEHEADER()
  432. {
  433. unSet($this->m_nLeft);
  434. unSet($this->m_nTop);
  435. unSet($this->m_nWidth);
  436. unSet($this->m_nHeight);
  437. unSet($this->m_bLocalClr);
  438. unSet($this->m_bInterlace);
  439. unSet($this->m_bSorted);
  440. unSet($this->m_nTableSize);
  441. unSet($this->m_colorTable);
  442. }
  443. ///////////////////////////////////////////////////////////////////////////
  444. function load($lpData, &$hdrLen)
  445. {
  446. $hdrLen = 0;
  447. $this->m_nLeft = $this->w2i(substr($lpData, 0, 2));
  448. $this->m_nTop = $this->w2i(substr($lpData, 2, 2));
  449. $this->m_nWidth = $this->w2i(substr($lpData, 4, 2));
  450. $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
  451. if(!$this->m_nWidth || !$this->m_nHeight) {
  452. return false;
  453. }
  454. $b = ord($lpData{8});
  455. $this->m_bLocalClr = ($b & 0x80) ? true : false;
  456. $this->m_bInterlace = ($b & 0x40) ? true : false;
  457. $this->m_bSorted = ($b & 0x20) ? true : false;
  458. $this->m_nTableSize = 2 << ($b & 0x07);
  459. $hdrLen = 9;
  460. if($this->m_bLocalClr) {
  461. $this->m_colorTable = new CGIFCOLORTABLE();
  462. if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
  463. return false;
  464. }
  465. $hdrLen += 3 * $this->m_nTableSize;
  466. }
  467. return true;
  468. }
  469. ///////////////////////////////////////////////////////////////////////////
  470. function w2i($str)
  471. {
  472. return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
  473. }
  474. }
  475. ///////////////////////////////////////////////////////////////////////////////////////////////////
  476. class CGIFIMAGE
  477. {
  478. var $m_disp;
  479. var $m_bUser;
  480. var $m_bTrans;
  481. var $m_nDelay;
  482. var $m_nTrans;
  483. var $m_lpComm;
  484. var $m_gih;
  485. var $m_data;
  486. var $m_lzw;
  487. ///////////////////////////////////////////////////////////////////////////
  488. function CGIFIMAGE()
  489. {
  490. unSet($this->m_disp);
  491. unSet($this->m_bUser);
  492. unSet($this->m_bTrans);
  493. unSet($this->m_nDelay);
  494. unSet($this->m_nTrans);
  495. unSet($this->m_lpComm);
  496. unSet($this->m_data);
  497. $this->m_gih = new CGIFIMAGEHEADER();
  498. $this->m_lzw = new CGIFLZW();
  499. }
  500. ///////////////////////////////////////////////////////////////////////////
  501. function load($data, &$datLen)
  502. {
  503. $datLen = 0;
  504. while(true) {
  505. $b = ord($data{0});
  506. $data = substr($data, 1);
  507. $datLen++;
  508. switch($b) {
  509. case 0x21: // Extension
  510. $len = 0;
  511. if(!$this->skipExt($data, $len)) {
  512. return false;
  513. }
  514. $datLen += $len;
  515. break;
  516. case 0x2C: // Image
  517. // LOAD HEADER & COLOR TABLE
  518. $len = 0;
  519. if(!$this->m_gih->load($data, $len)) {
  520. return false;
  521. }
  522. $data = substr($data, $len);
  523. $datLen += $len;
  524. // ALLOC BUFFER
  525. $len = 0;
  526. if(!($this->m_data = $this->m_lzw->deCompress($data, $len))) {
  527. return false;
  528. }
  529. $data = substr($data, $len);
  530. $datLen += $len;
  531. if($this->m_gih->m_bInterlace) {
  532. $this->deInterlace();
  533. }
  534. return true;
  535. case 0x3B: // EOF
  536. default:
  537. return false;
  538. }
  539. }
  540. return false;
  541. }
  542. ///////////////////////////////////////////////////////////////////////////
  543. function skipExt(&$data, &$extLen)
  544. {
  545. $extLen = 0;
  546. $b = ord($data{0});
  547. $data = substr($data, 1);
  548. $extLen++;
  549. switch($b) {
  550. case 0xF9: // Graphic Control
  551. $b = ord($data{1});
  552. $this->m_disp = ($b & 0x1C) >> 2;
  553. $this->m_bUser = ($b & 0x02) ? true : false;
  554. $this->m_bTrans = ($b & 0x01) ? true : false;
  555. $this->m_nDelay = $this->w2i(substr($data, 2, 2));
  556. $this->m_nTrans = ord($data{4});
  557. break;
  558. case 0xFE: // Comment
  559. $this->m_lpComm = substr($data, 1, ord($data{0}));
  560. break;
  561. case 0x01: // Plain text
  562. break;
  563. case 0xFF: // Application
  564. break;
  565. }
  566. // SKIP DEFAULT AS DEFS MAY CHANGE
  567. $b = ord($data{0});
  568. $data = substr($data, 1);
  569. $extLen++;
  570. while($b > 0) {
  571. $data = substr($data, $b);
  572. $extLen += $b;
  573. $b = ord($data{0});
  574. $data = substr($data, 1);
  575. $extLen++;
  576. }
  577. return true;
  578. }
  579. ///////////////////////////////////////////////////////////////////////////
  580. function w2i($str)
  581. {
  582. return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
  583. }
  584. ///////////////////////////////////////////////////////////////////////////
  585. function deInterlace()
  586. {
  587. $data = $this->m_data;
  588. for($i = 0; $i < 4; $i++) {
  589. switch($i) {
  590. case 0:
  591. $s = 8;
  592. $y = 0;
  593. break;
  594. case 1:
  595. $s = 8;
  596. $y = 4;
  597. break;
  598. case 2:
  599. $s = 4;
  600. $y = 2;
  601. break;
  602. case 3:
  603. $s = 2;
  604. $y = 1;
  605. break;
  606. }
  607. for(; $y < $this->m_gih->m_nHeight; $y += $s) {
  608. $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
  609. $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
  610. $data =
  611. substr($data, 0, $y * $this->m_gih->m_nWidth) .
  612. $lne .
  613. substr($data, ($y + 1) * $this->m_gih->m_nWidth);
  614. }
  615. }
  616. $this->m_data = $data;
  617. }
  618. }
  619. ///////////////////////////////////////////////////////////////////////////////////////////////////
  620. class CGIF
  621. {
  622. var $m_gfh;
  623. var $m_lpData;
  624. var $m_img;
  625. var $m_bLoaded;
  626. ///////////////////////////////////////////////////////////////////////////
  627. // CONSTRUCTOR
  628. function CGIF()
  629. {
  630. $this->m_gfh = new CGIFFILEHEADER();
  631. $this->m_img = new CGIFIMAGE();
  632. $this->m_lpData = "";
  633. $this->m_bLoaded = false;
  634. }
  635. ///////////////////////////////////////////////////////////////////////////
  636. function loadFile($lpszFileName, $iIndex)
  637. {
  638. if($iIndex < 0) {
  639. return false;
  640. }
  641. // READ FILE
  642. if(!($fh = @fOpen($lpszFileName, "rb"))) {
  643. return false;
  644. }
  645. //EDITEI - in order to read remote files (HTTP(s) and FTP protocols)
  646. if ( strpos($lpszFileName,"http") !== false or strpos($lpszFileName,"ftp") !== false )
  647. {
  648. $contents = '';
  649. while (!feof($fh)) $contents .= @fread($fh, 8192);
  650. }
  651. else
  652. {
  653. $contents = @fread($fh,@filesize($lpszFileName) );
  654. }
  655. $this->m_lpData = $contents;
  656. // $this->m_lpData = @fRead($fh, @fileSize($lpszFileName));
  657. fClose($fh);
  658. // GET FILE HEADER
  659. $len = 0;
  660. if(!$this->m_gfh->load($this->m_lpData, $len)) {
  661. return false;
  662. }
  663. $this->m_lpData = substr($this->m_lpData, $len);
  664. do {
  665. $imgLen = 0;
  666. if(!$this->m_img->load($this->m_lpData, $imgLen)) {
  667. return false;
  668. }
  669. $this->m_lpData = substr($this->m_lpData, $imgLen);
  670. }
  671. while($iIndex-- > 0);
  672. $this->m_bLoaded = true;
  673. return true;
  674. }
  675. ///////////////////////////////////////////////////////////////////////////
  676. function getSize($lpszFileName, &$width, &$height)
  677. {
  678. if(!($fh = @fOpen($lpszFileName, "rb"))) {
  679. return false;
  680. }
  681. $data = @fRead($fh, @fileSize($lpszFileName));
  682. @fClose($fh);
  683. $gfh = new CGIFFILEHEADER();
  684. $len = 0;
  685. if(!$gfh->load($data, $len)) {
  686. return false;
  687. }
  688. $width = $gfh->m_nWidth;
  689. $height = $gfh->m_nHeight;
  690. return true;
  691. }
  692. ///////////////////////////////////////////////////////////////////////////
  693. function getBmp($bgColor)
  694. {
  695. $out = "";
  696. if(!$this->m_bLoaded) {
  697. return false;
  698. }
  699. // PREPARE COLOR TABLE (RGBQUADs)
  700. if($this->m_img->m_gih->m_bLocalClr) {
  701. $nColors = $this->m_img->m_gih->m_nTableSize;
  702. $rgbq = $this->m_img->m_gih->m_colorTable->toRGBQuad();
  703. if($bgColor != -1) {
  704. $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
  705. }
  706. }
  707. else if($this->m_gfh->m_bGlobalClr) {
  708. $nColors = $this->m_gfh->m_nTableSize;
  709. $rgbq = $this->m_gfh->m_colorTable->toRGBQuad();
  710. if($bgColor != -1) {
  711. $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
  712. }
  713. }
  714. else {
  715. $nColors = 0;
  716. $bgColor = -1;
  717. }
  718. // PREPARE BITMAP BITS
  719. $data = $this->m_img->m_data;
  720. $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
  721. $bmp = "";
  722. $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0;
  723. for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
  724. for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
  725. if(
  726. ($x >= $this->m_img->m_gih->m_nLeft) &&
  727. ($y >= $this->m_img->m_gih->m_nTop) &&
  728. ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
  729. ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
  730. // PART OF IMAGE
  731. if($this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
  732. // TRANSPARENT -> BACKGROUND
  733. if($bgColor == -1) {
  734. $bmp .= chr($this->m_gfh->m_nBgColor);
  735. }
  736. else {
  737. $bmp .= chr($bgColor);
  738. }
  739. }
  740. else {
  741. $bmp .= $data{$nPxl};
  742. }
  743. }
  744. else {
  745. // BACKGROUND
  746. if($bgColor == -1) {
  747. $bmp .= chr($this->m_gfh->m_nBgColor);
  748. }
  749. else {
  750. $bmp .= chr($bgColor);
  751. }
  752. }
  753. }
  754. $nPxl -= $this->m_gfh->m_nWidth << 1;
  755. // ADD PADDING
  756. for($x = 0; $x < $nPad; $x++) {
  757. $bmp .= "\x00";
  758. }
  759. }
  760. // BITMAPFILEHEADER
  761. $out .= "BM";
  762. $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp));
  763. $out .= "\x00\x00";
  764. $out .= "\x00\x00";
  765. $out .= $this->dword(14 + 40 + ($nColors << 2));
  766. // BITMAPINFOHEADER
  767. $out .= $this->dword(40);
  768. $out .= $this->dword($this->m_gfh->m_nWidth);
  769. $out .= $this->dword($this->m_gfh->m_nHeight);
  770. $out .= "\x01\x00";
  771. $out .= "\x08\x00";
  772. $out .= "\x00\x00\x00\x00";
  773. $out .= "\x00\x00\x00\x00";
  774. $out .= "\x12\x0B\x00\x00";
  775. $out .= "\x12\x0B\x00\x00";
  776. $out .= $this->dword($nColors % 256);
  777. $out .= "\x00\x00\x00\x00";
  778. // COLOR TABLE
  779. if($nColors > 0) {
  780. $out .= $rgbq;
  781. }
  782. // DATA
  783. $out .= $bmp;
  784. return $out;
  785. }
  786. ///////////////////////////////////////////////////////////////////////////
  787. function getPng($bgColor)
  788. {
  789. $out = "";
  790. if(!$this->m_bLoaded) {
  791. return false;
  792. }
  793. // PREPARE COLOR TABLE (RGBQUADs)
  794. if($this->m_img->m_gih->m_bLocalClr) {
  795. $nColors = $this->m_img->m_gih->m_nTableSize;
  796. $pal = $this->m_img->m_gih->m_colorTable->toString();
  797. if($bgColor != -1) {
  798. $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
  799. }
  800. }
  801. else if($this->m_gfh->m_bGlobalClr) {
  802. $nColors = $this->m_gfh->m_nTableSize;
  803. $pal = $this->m_gfh->m_colorTable->toString();
  804. if($bgColor != -1) {
  805. $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
  806. }
  807. }
  808. else {
  809. $nColors = 0;
  810. $bgColor = -1;
  811. }
  812. // PREPARE BITMAP BITS
  813. $data = $this->m_img->m_data;
  814. $nPxl = 0;
  815. $bmp = "";
  816. for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
  817. $bmp .= "\x00";
  818. for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
  819. if(
  820. ($x >= $this->m_img->m_gih->m_nLeft) &&
  821. ($y >= $this->m_img->m_gih->m_nTop) &&
  822. ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
  823. ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
  824. // PART OF IMAGE
  825. $bmp .= $data{$nPxl};
  826. }
  827. else {
  828. // BACKGROUND
  829. if($bgColor == -1) {
  830. $bmp .= chr($this->m_gfh->m_nBgColor);
  831. }
  832. else {
  833. $bmp .= chr($bgColor);
  834. }
  835. }
  836. }
  837. }
  838. $bmp = gzcompress($bmp, 9);
  839. ///////////////////////////////////////////////////////////////////////
  840. // SIGNATURE
  841. $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
  842. ///////////////////////////////////////////////////////////////////////
  843. // HEADER
  844. $out .= "\x00\x00\x00\x0D";
  845. $tmp = "IHDR";
  846. $tmp .= $this->ndword($this->m_gfh->m_nWidth);
  847. $tmp .= $this->ndword($this->m_gfh->m_nHeight);
  848. $tmp .= "\x08\x03\x00\x00\x00";
  849. $out .= $tmp;
  850. $out .= $this->ndword(crc32($tmp));
  851. ///////////////////////////////////////////////////////////////////////
  852. // PALETTE
  853. if($nColors > 0) {
  854. $out .= $this->ndword($nColors * 3);
  855. $tmp = "PLTE";
  856. $tmp .= $pal;
  857. $out .= $tmp;
  858. $out .= $this->ndword(crc32($tmp));
  859. }
  860. ///////////////////////////////////////////////////////////////////////
  861. // TRANSPARENCY
  862. if($this->m_img->m_bTrans && ($nColors > 0)) {
  863. $out .= $this->ndword($nColors);
  864. $tmp = "tRNS";
  865. for($i = 0; $i < $nColors; $i++) {
  866. $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF";
  867. }
  868. $out .= $tmp;
  869. $out .= $this->ndword(crc32($tmp));
  870. }
  871. ///////////////////////////////////////////////////////////////////////
  872. // DATA BITS
  873. $out .= $this->ndword(strlen($bmp));
  874. $tmp = "IDAT";
  875. $tmp .= $bmp;
  876. $out .= $tmp;
  877. $out .= $this->ndword(crc32($tmp));
  878. ///////////////////////////////////////////////////////////////////////
  879. // END OF FILE
  880. $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82";
  881. return $out;
  882. }
  883. ///////////////////////////////////////////////////////////////////////////
  884. function dword($val)
  885. {
  886. $val = intval($val);
  887. return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
  888. }
  889. ///////////////////////////////////////////////////////////////////////////
  890. function ndword($val)
  891. {
  892. $val = intval($val);
  893. return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
  894. }
  895. ///////////////////////////////////////////////////////////////////////////
  896. function width()
  897. {
  898. return $this->m_gfh->m_nWidth;
  899. }
  900. ///////////////////////////////////////////////////////////////////////////
  901. function height()
  902. {
  903. return $this->m_gfh->m_nHeight;
  904. }
  905. ///////////////////////////////////////////////////////////////////////////
  906. function comment()
  907. {
  908. return $this->m_img->m_lpComm;
  909. }
  910. ///////////////////////////////////////////////////////////////////////////
  911. function loaded()
  912. {
  913. return $this->m_bLoaded;
  914. }
  915. }
  916. ///////////////////////////////////////////////////////////////////////////////////////////////////
  917. ?>