2 ///////////////////////////////////////////////////////////////////////////////////////////////////
3 // GIF Util - (C) 2003 Yamasoft (S/C)
4 // http://www.yamasoft.com
6 // This file can be freely copied, distributed, modified, updated by anyone under the only
7 // condition to leave the original address (Yamasoft, http://www.yamasoft.com) and this header.
8 ///////////////////////////////////////////////////////////////////////////////////////////////////
9 // <gif> = gif_loadFile(filename, [index])
10 // <bool> = gif_getSize(<gif> or filename, &width, &height)
11 // <bool> = gif_outputAsPng(<gif>, filename, [bgColor])
12 // <bool> = gif_outputAsBmp(<gif>, filename, [bgcolor])
13 // <bool> = gif_outputAsJpeg(<gif>, filename, [bgcolor]) - use cjpeg if available otherwise uses GD
14 ///////////////////////////////////////////////////////////////////////////////////////////////////
15 // Original code by Fabien Ezber
16 // Modified by James Heinrich <info@silisoftware.com> for use in phpThumb() - December 10, 2003
17 // * Added function gif_loadFileToGDimageResource() - this returns a GD image resource
18 // * Modified gif_outputAsJpeg() to check if it's running under Windows, or if cjpeg is not
19 // available, in which case it will attempt to output JPEG using GD functions
20 // * added @ error-suppression to two lines where it checks: if ($this->m_img->m_bTrans)
21 // otherwise warnings are generated if error_reporting == E_ALL
22 ///////////////////////////////////////////////////////////////////////////////////////////////////
24 function gif_loadFile($lpszFileName, $iIndex = 0)
27 if ($gif->loadFile($lpszFileName, $iIndex)) {
33 ///////////////////////////////////////////////////////////////////////////////////////////////////
35 // Added by James Heinrich <info@silisoftware.com> - December 10, 2003
36 function gif_loadFileToGDimageResource($gifFilename, $bgColor = -1)
38 if ($gif = gif_loadFile($gifFilename)) {
41 // general strategy: convert raw data to PNG then convert PNG data to GD image resource
42 $PNGdata = $gif->getPng($bgColor);
43 if ($img = @ImageCreateFromString($PNGdata)) {
45 // excellent - PNG image data successfully converted to GD image
48 } elseif ($img = $gif->getGD_PixelPlotterVersion()) {
50 // problem: ImageCreateFromString() didn't like the PNG image data.
51 // This has been known to happen in PHP v4.0.6
52 // solution: take the raw image data and create a new GD image and plot
53 // pixel-by-pixel on the GD image. This is extremely slow, but it does
54 // work and a slow solution is better than no solution, right? :)
62 ///////////////////////////////////////////////////////////////////////////////////////////////////
64 function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1)
66 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
70 $fd = $gif->getBmp($bgColor);
71 if (strlen($fd) <= 0) {
75 if (!($fh = @fopen($lpszFileName, 'wb'))) {
78 @fwrite($fh, $fd, strlen($fd));
84 ///////////////////////////////////////////////////////////////////////////////////////////////////
86 function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1)
88 if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
92 $fd = $gif->getPng($bgColor);
93 if (strlen($fd) <= 0) {
97 if (!($fh = @fopen($lpszFileName, 'wb'))) {
100 @fwrite($fh, $fd, strlen($fd));
106 ///////////////////////////////////////////////////////////////////////////////////////////////////
108 function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1)
110 // JPEG output that does not require cjpeg added by James Heinrich <info@silisoftware.com> - December 10, 2003
111 if ((strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') && (file_exists('/usr/local/bin/cjpeg') || `which cjpeg`)) {
113 if (gif_outputAsBmp($gif, $lpszFileName.'.bmp', $bgColor)) {
114 exec('cjpeg '.$lpszFileName.'.bmp >'.$lpszFileName.' 2>/dev/null');
115 @unLink($lpszFileName.'.bmp');
117 if (@file_exists($lpszFileName)) {
118 if (@fileSize($lpszFileName) > 0) {
122 @unLink($lpszFileName);
128 // either Windows, or cjpeg not found in path
129 if ($img = @ImageCreateFromString($gif->getPng($bgColor))) {
130 if (@ImageJPEG($img, $lpszFileName)) {
140 ///////////////////////////////////////////////////////////////////////////////////////////////////
142 function gif_getSize($gif, &$width, &$height)
144 if (isSet($gif) && (@get_class($gif) == 'cgif') && $gif->loaded()) {
145 $width = $gif->width();
146 $height = $gif->height();
147 } elseif (@file_exists($gif)) {
149 if (!$myGIF->getSize($gif, $width, $height)) {
159 ///////////////////////////////////////////////////////////////////////////////////////////////////
164 var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
165 var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
167 ///////////////////////////////////////////////////////////////////////////
172 $this->MAX_LZW_BITS = 12;
178 $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1);
179 $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1);
180 $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
181 $this->Buf = range(0, 279);
184 ///////////////////////////////////////////////////////////////////////////
186 function deCompress($data, &$datLen)
188 $stLen = strlen($data);
193 $this->LZWCommand($data, true);
195 while (($iIndex = $this->LZWCommand($data, false)) >= 0) {
196 $ret .= chr($iIndex);
199 $datLen = $stLen - strlen($data);
208 ///////////////////////////////////////////////////////////////////////////
210 function LZWCommand(&$data, $bInit)
213 $this->SetCodeSize = ord($data{0});
214 $data = substr($data, 1);
216 $this->CodeSize = $this->SetCodeSize + 1;
217 $this->ClearCode = 1 << $this->SetCodeSize;
218 $this->EndCode = $this->ClearCode + 1;
219 $this->MaxCode = $this->ClearCode + 2;
220 $this->MaxCodeSize = $this->ClearCode << 1;
222 $this->GetCode($data, $bInit);
225 for ($i = 0; $i < $this->ClearCode; $i++) {
227 $this->Vals[$i] = $i;
230 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
242 $this->FirstCode = $this->GetCode($data, $bInit);
243 $this->OldCode = $this->FirstCode;
245 while ($this->FirstCode == $this->ClearCode);
247 return $this->FirstCode;
252 return $this->Stack[$this->sp];
255 while (($Code = $this->GetCode($data, $bInit)) >= 0) {
256 if ($Code == $this->ClearCode) {
257 for ($i = 0; $i < $this->ClearCode; $i++) {
259 $this->Vals[$i] = $i;
262 for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
267 $this->CodeSize = $this->SetCodeSize + 1;
268 $this->MaxCodeSize = $this->ClearCode << 1;
269 $this->MaxCode = $this->ClearCode + 2;
271 $this->FirstCode = $this->GetCode($data, $bInit);
272 $this->OldCode = $this->FirstCode;
274 return $this->FirstCode;
277 if ($Code == $this->EndCode) {
282 if ($Code >= $this->MaxCode) {
283 $this->Stack[$this->sp] = $this->FirstCode;
285 $Code = $this->OldCode;
288 while ($Code >= $this->ClearCode) {
289 $this->Stack[$this->sp] = $this->Vals[$Code];
292 if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
295 $Code = $this->Next[$Code];
298 $this->FirstCode = $this->Vals[$Code];
299 $this->Stack[$this->sp] = $this->FirstCode;
302 if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
303 $this->Next[$Code] = $this->OldCode;
304 $this->Vals[$Code] = $this->FirstCode;
307 if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
308 $this->MaxCodeSize *= 2;
313 $this->OldCode = $InCode;
316 return $this->Stack[$this->sp];
323 ///////////////////////////////////////////////////////////////////////////
325 function GetCode(&$data, $bInit)
335 if (($this->CurBit + $this->CodeSize) >= $this->LastBit) {
337 if ($this->CurBit >= $this->LastBit) {
338 // Ran off the end of my bits
344 $this->Buf[0] = $this->Buf[$this->LastByte - 2];
345 $this->Buf[1] = $this->Buf[$this->LastByte - 1];
347 $Count = ord($data{0});
348 $data = substr($data, 1);
351 for ($i = 0; $i < $Count; $i++) {
352 $this->Buf[2 + $i] = ord($data{$i});
354 $data = substr($data, $Count);
359 $this->LastByte = 2 + $Count;
360 $this->CurBit = ($this->CurBit - $this->LastBit) + 16;
361 $this->LastBit = (2 + $Count) << 3;
365 for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
366 $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j;
369 $this->CurBit += $this->CodeSize;
374 ///////////////////////////////////////////////////////////////////////////////////////////////////
381 ///////////////////////////////////////////////////////////////////////////
384 function CGIFCOLORTABLE()
386 unSet($this->m_nColors);
387 unSet($this->m_arColors);
390 ///////////////////////////////////////////////////////////////////////////
392 function load($lpData, $num)
394 $this->m_nColors = 0;
395 $this->m_arColors = array();
397 for ($i = 0; $i < $num; $i++) {
398 $rgb = substr($lpData, $i * 3, 3);
399 if (strlen($rgb) < 3) {
403 $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0});
410 ///////////////////////////////////////////////////////////////////////////
416 for ($i = 0; $i < $this->m_nColors; $i++) {
418 chr(($this->m_arColors[$i] & 0x000000FF)) . // R
419 chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
420 chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
426 ///////////////////////////////////////////////////////////////////////////
432 for ($i = 0; $i < $this->m_nColors; $i++) {
434 chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
435 chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G
436 chr(($this->m_arColors[$i] & 0x000000FF)) . // R
443 ///////////////////////////////////////////////////////////////////////////
445 function colorIndex($rgb)
447 $rgb = intval($rgb) & 0xFFFFFF;
448 $r1 = ($rgb & 0x0000FF);
449 $g1 = ($rgb & 0x00FF00) >> 8;
450 $b1 = ($rgb & 0xFF0000) >> 16;
453 for ($i = 0; $i < $this->m_nColors; $i++) {
454 $r2 = ($this->m_arColors[$i] & 0x000000FF);
455 $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
456 $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
457 $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
459 if (($idx == -1) || ($d < $dif)) {
469 ///////////////////////////////////////////////////////////////////////////////////////////////////
484 ///////////////////////////////////////////////////////////////////////////
487 function CGIFFILEHEADER()
489 unSet($this->m_lpVer);
490 unSet($this->m_nWidth);
491 unSet($this->m_nHeight);
492 unSet($this->m_bGlobalClr);
493 unSet($this->m_nColorRes);
494 unSet($this->m_bSorted);
495 unSet($this->m_nTableSize);
496 unSet($this->m_nBgColor);
497 unSet($this->m_nPixelRatio);
498 unSet($this->m_colorTable);
501 ///////////////////////////////////////////////////////////////////////////
503 function load($lpData, &$hdrLen)
507 $this->m_lpVer = substr($lpData, 0, 6);
508 if (($this->m_lpVer <> 'GIF87a') && ($this->m_lpVer <> 'GIF89a')) {
512 $this->m_nWidth = $this->w2i(substr($lpData, 6, 2));
513 $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
514 if (!$this->m_nWidth || !$this->m_nHeight) {
518 $b = ord(substr($lpData, 10, 1));
519 $this->m_bGlobalClr = ($b & 0x80) ? true : false;
520 $this->m_nColorRes = ($b & 0x70) >> 4;
521 $this->m_bSorted = ($b & 0x08) ? true : false;
522 $this->m_nTableSize = 2 << ($b & 0x07);
523 $this->m_nBgColor = ord(substr($lpData, 11, 1));
524 $this->m_nPixelRatio = ord(substr($lpData, 12, 1));
527 if ($this->m_bGlobalClr) {
528 $this->m_colorTable = new CGIFCOLORTABLE();
529 if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
532 $hdrLen += 3 * $this->m_nTableSize;
538 ///////////////////////////////////////////////////////////////////////////
542 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
546 ///////////////////////////////////////////////////////////////////////////////////////////////////
548 class CGIFIMAGEHEADER
560 ///////////////////////////////////////////////////////////////////////////
563 function CGIFIMAGEHEADER()
565 unSet($this->m_nLeft);
566 unSet($this->m_nTop);
567 unSet($this->m_nWidth);
568 unSet($this->m_nHeight);
569 unSet($this->m_bLocalClr);
570 unSet($this->m_bInterlace);
571 unSet($this->m_bSorted);
572 unSet($this->m_nTableSize);
573 unSet($this->m_colorTable);
576 ///////////////////////////////////////////////////////////////////////////
578 function load($lpData, &$hdrLen)
582 $this->m_nLeft = $this->w2i(substr($lpData, 0, 2));
583 $this->m_nTop = $this->w2i(substr($lpData, 2, 2));
584 $this->m_nWidth = $this->w2i(substr($lpData, 4, 2));
585 $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
587 if (!$this->m_nWidth || !$this->m_nHeight) {
591 $b = ord($lpData{8});
592 $this->m_bLocalClr = ($b & 0x80) ? true : false;
593 $this->m_bInterlace = ($b & 0x40) ? true : false;
594 $this->m_bSorted = ($b & 0x20) ? true : false;
595 $this->m_nTableSize = 2 << ($b & 0x07);
598 if ($this->m_bLocalClr) {
599 $this->m_colorTable = new CGIFCOLORTABLE();
600 if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
603 $hdrLen += 3 * $this->m_nTableSize;
609 ///////////////////////////////////////////////////////////////////////////
613 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
617 ///////////////////////////////////////////////////////////////////////////////////////////////////
631 ///////////////////////////////////////////////////////////////////////////
635 unSet($this->m_disp);
636 unSet($this->m_bUser);
637 unSet($this->m_bTrans);
638 unSet($this->m_nDelay);
639 unSet($this->m_nTrans);
640 unSet($this->m_lpComm);
641 unSet($this->m_data);
642 $this->m_gih = new CGIFIMAGEHEADER();
643 $this->m_lzw = new CGIFLZW();
646 ///////////////////////////////////////////////////////////////////////////
648 function load($data, &$datLen)
654 $data = substr($data, 1);
658 case 0x21: // Extension
659 if (!$this->skipExt($data, $len = 0)) {
666 // LOAD HEADER & COLOR TABLE
667 if (!$this->m_gih->load($data, $len = 0)) {
670 $data = substr($data, $len);
674 if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
677 $data = substr($data, $len);
680 if ($this->m_gih->m_bInterlace) {
681 $this->deInterlace();
693 ///////////////////////////////////////////////////////////////////////////
695 function skipExt(&$data, &$extLen)
700 $data = substr($data, 1);
704 case 0xF9: // Graphic Control
706 $this->m_disp = ($b & 0x1C) >> 2;
707 $this->m_bUser = ($b & 0x02) ? true : false;
708 $this->m_bTrans = ($b & 0x01) ? true : false;
709 $this->m_nDelay = $this->w2i(substr($data, 2, 2));
710 $this->m_nTrans = ord($data{4});
713 case 0xFE: // Comment
714 $this->m_lpComm = substr($data, 1, ord($data{0}));
717 case 0x01: // Plain text
720 case 0xFF: // Application
724 // SKIP DEFAULT AS DEFS MAY CHANGE
726 $data = substr($data, 1);
729 $data = substr($data, $b);
732 $data = substr($data, 1);
738 ///////////////////////////////////////////////////////////////////////////
742 return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8);
745 ///////////////////////////////////////////////////////////////////////////
747 function deInterlace()
749 $data = $this->m_data;
751 for ($i = 0; $i < 4; $i++) {
774 for (; $y < $this->m_gih->m_nHeight; $y += $s) {
775 $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
776 $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
779 substr($data, 0, $y * $this->m_gih->m_nWidth) .
781 substr($data, ($y + 1) * $this->m_gih->m_nWidth);
785 $this->m_data = $data;
789 ///////////////////////////////////////////////////////////////////////////////////////////////////
798 ///////////////////////////////////////////////////////////////////////////
803 $this->m_gfh = new CGIFFILEHEADER();
804 $this->m_img = new CGIFIMAGE();
805 $this->m_lpData = '';
806 $this->m_bLoaded = false;
809 ///////////////////////////////////////////////////////////////////////////
811 function loadFile($lpszFileName, $iIndex)
818 if (!($fh = @fopen($lpszFileName, 'rb'))) {
821 $this->m_lpData = @fRead($fh, @fileSize($lpszFileName));
825 if (!$this->m_gfh->load($this->m_lpData, $len = 0)) {
828 $this->m_lpData = substr($this->m_lpData, $len);
831 if (!$this->m_img->load($this->m_lpData, $imgLen = 0)) {
834 $this->m_lpData = substr($this->m_lpData, $imgLen);
836 while ($iIndex-- > 0);
838 $this->m_bLoaded = true;
842 ///////////////////////////////////////////////////////////////////////////
844 function getSize($lpszFileName, &$width, &$height)
846 if (!($fh = @fopen($lpszFileName, 'rb'))) {
849 $data = @fRead($fh, @fileSize($lpszFileName));
852 $gfh = new CGIFFILEHEADER();
853 if (!$gfh->load($data, $len = 0)) {
857 $width = $gfh->m_nWidth;
858 $height = $gfh->m_nHeight;
862 ///////////////////////////////////////////////////////////////////////////
864 function getBmp($bgColor)
868 if (!$this->m_bLoaded) {
872 // PREPARE COLOR TABLE (RGBQUADs)
873 if ($this->m_img->m_gih->m_bLocalClr) {
874 $nColors = $this->m_img->m_gih->m_nTableSize;
875 $rgbq = $this->m_img->m_gih->m_colorTable->toRGBQuad();
876 if ($bgColor != -1) {
877 $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
879 } elseif ($this->m_gfh->m_bGlobalClr) {
880 $nColors = $this->m_gfh->m_nTableSize;
881 $rgbq = $this->m_gfh->m_colorTable->toRGBQuad();
882 if ($bgColor != -1) {
883 $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
890 // PREPARE BITMAP BITS
891 $data = $this->m_img->m_data;
892 $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
894 $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0;
895 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
896 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
898 ($x >= $this->m_img->m_gih->m_nLeft) &&
899 ($y >= $this->m_img->m_gih->m_nTop) &&
900 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
901 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
903 if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
904 // TRANSPARENT -> BACKGROUND
905 if ($bgColor == -1) {
906 $bmp .= chr($this->m_gfh->m_nBgColor);
908 $bmp .= chr($bgColor);
911 $bmp .= $data{$nPxl};
915 if ($bgColor == -1) {
916 $bmp .= chr($this->m_gfh->m_nBgColor);
918 $bmp .= chr($bgColor);
922 $nPxl -= $this->m_gfh->m_nWidth << 1;
925 for ($x = 0; $x < $nPad; $x++) {
932 $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp));
935 $out .= $this->dword(14 + 40 + ($nColors << 2));
938 $out .= $this->dword(40);
939 $out .= $this->dword($this->m_gfh->m_nWidth);
940 $out .= $this->dword($this->m_gfh->m_nHeight);
943 $out .= "\x00\x00\x00\x00";
944 $out .= "\x00\x00\x00\x00";
945 $out .= "\x12\x0B\x00\x00";
946 $out .= "\x12\x0B\x00\x00";
947 $out .= $this->dword($nColors % 256);
948 $out .= "\x00\x00\x00\x00";
961 ///////////////////////////////////////////////////////////////////////////
963 function getPng($bgColor)
967 if (!$this->m_bLoaded) {
971 // PREPARE COLOR TABLE (RGBQUADs)
972 if ($this->m_img->m_gih->m_bLocalClr) {
973 $nColors = $this->m_img->m_gih->m_nTableSize;
974 $pal = $this->m_img->m_gih->m_colorTable->toString();
975 if ($bgColor != -1) {
976 $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
978 } elseif ($this->m_gfh->m_bGlobalClr) {
979 $nColors = $this->m_gfh->m_nTableSize;
980 $pal = $this->m_gfh->m_colorTable->toString();
981 if ($bgColor != -1) {
982 $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
989 // PREPARE BITMAP BITS
990 $data = $this->m_img->m_data;
993 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
995 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
997 ($x >= $this->m_img->m_gih->m_nLeft) &&
998 ($y >= $this->m_img->m_gih->m_nTop) &&
999 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1000 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1002 $bmp .= $data{$nPxl};
1005 if ($bgColor == -1) {
1006 $bmp .= chr($this->m_gfh->m_nBgColor);
1008 $bmp .= chr($bgColor);
1013 $bmp = gzcompress($bmp, 9);
1015 ///////////////////////////////////////////////////////////////////////
1017 $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
1018 ///////////////////////////////////////////////////////////////////////
1020 $out .= "\x00\x00\x00\x0D";
1022 $tmp .= $this->ndword($this->m_gfh->m_nWidth);
1023 $tmp .= $this->ndword($this->m_gfh->m_nHeight);
1024 $tmp .= "\x08\x03\x00\x00\x00";
1026 $out .= $this->ndword(crc32($tmp));
1027 ///////////////////////////////////////////////////////////////////////
1030 $out .= $this->ndword($nColors * 3);
1034 $out .= $this->ndword(crc32($tmp));
1036 ///////////////////////////////////////////////////////////////////////
1038 if (@$this->m_img->m_bTrans && ($nColors > 0)) {
1039 $out .= $this->ndword($nColors);
1041 for ($i = 0; $i < $nColors; $i++) {
1042 $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF";
1045 $out .= $this->ndword(crc32($tmp));
1047 ///////////////////////////////////////////////////////////////////////
1049 $out .= $this->ndword(strlen($bmp));
1053 $out .= $this->ndword(crc32($tmp));
1054 ///////////////////////////////////////////////////////////////////////
1056 $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82";
1061 ///////////////////////////////////////////////////////////////////////////
1063 // Added by James Heinrich <info@silisoftware.com> - January 5, 2003
1065 // Takes raw image data and plots it pixel-by-pixel on a new GD image and returns that
1066 // It's extremely slow, but the only solution when ImageCreateFromString() fails
1067 function getGD_PixelPlotterVersion()
1069 if (!$this->m_bLoaded) {
1073 // PREPARE COLOR TABLE (RGBQUADs)
1074 if ($this->m_img->m_gih->m_bLocalClr) {
1075 $pal = $this->m_img->m_gih->m_colorTable->toString();
1076 } elseif ($this->m_gfh->m_bGlobalClr) {
1077 $pal = $this->m_gfh->m_colorTable->toString();
1079 die('No color table available in getGD_PixelPlotterVersion()');
1082 $PlottingIMG = ImageCreate($this->m_gfh->m_nWidth, $this->m_gfh->m_nHeight);
1083 $NumColorsInPal = floor(strlen($pal) / 3);
1084 for ($i = 0; $i < $NumColorsInPal; $i++) {
1085 $ThisImageColor[$i] = ImageColorAllocate(
1087 ord($pal{(($i * 3) + 0)}),
1088 ord($pal{(($i * 3) + 1)}),
1089 ord($pal{(($i * 3) + 2)}));
1092 // PREPARE BITMAP BITS
1093 $data = $this->m_img->m_data;
1094 $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
1095 for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1097 for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1099 ($x >= $this->m_img->m_gih->m_nLeft) &&
1100 ($y >= $this->m_img->m_gih->m_nTop) &&
1101 ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1102 ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1104 if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
1105 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1107 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[ord($data{$nPxl})]);
1111 ImageSetPixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1114 $nPxl -= $this->m_gfh->m_nWidth << 1;
1118 return $PlottingIMG;
1121 ///////////////////////////////////////////////////////////////////////////
1123 function dword($val)
1125 $val = intval($val);
1126 return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
1129 ///////////////////////////////////////////////////////////////////////////
1131 function ndword($val)
1133 $val = intval($val);
1134 return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
1137 ///////////////////////////////////////////////////////////////////////////
1141 return $this->m_gfh->m_nWidth;
1144 ///////////////////////////////////////////////////////////////////////////
1148 return $this->m_gfh->m_nHeight;
1151 ///////////////////////////////////////////////////////////////////////////
1155 return $this->m_img->m_lpComm;
1158 ///////////////////////////////////////////////////////////////////////////
1162 return $this->m_bLoaded;
1166 ///////////////////////////////////////////////////////////////////////////////////////////////////