= gif_loadFile(filename, [index]) // = gif_getSize( or filename, &width, &height) // = gif_outputAsPng(, filename, [bgColor]) // = gif_outputAsBmp(, filename, [bgcolor]) // = gif_outputAsJpeg(, filename, [bgcolor]) - Requires cjpeg /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_loadFile($lpszFileName, $iIndex = 0) { $gif = new CGIF(); if(!$gif->loadFile($lpszFileName, $iIndex)) { return false; } return $gif; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1) { if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) { return false; } $fd = $gif->getBmp($bgColor); if(strlen($fd) <= 0) { return false; } if(!($fh = @fOpen($lpszFileName, "wb"))) { return false; } @fWrite($fh, $fd, strlen($fd)); @fFlush($fh); @fClose($fh); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1) { if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) { return false; } $fd = $gif->getPng($bgColor); if(strlen($fd) <= 0) { return false; } if(!($fh = @fOpen($lpszFileName, "wb"))) { return false; } @fWrite($fh, $fd, strlen($fd)); @fFlush($fh); @fClose($fh); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1) { if(gif_outputAsBmp($gif, "$lpszFileName.bmp", $gbColor)) { exec("cjpeg $lpszFileName.bmp >$lpszFileName 2>/dev/null"); @unLink("$lpszFileName.bmp"); if(@file_exists($lpszFileName)) { if(@fileSize($lpszFileName) > 0) { return true; } @unLink($lpszFileName); } } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_getSize($gif, &$width, &$height) { if(isSet($gif) && (@get_class($gif) == "cgif") && $gif->loaded()) { $width = $gif->width(); $height = $gif->height(); } else if(@file_exists($gif)) { $myGIF = new CGIF(); if(!$myGIF->getSize($gif, $width, $height)) { return false; } } else { return false; } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFLZW { var $MAX_LZW_BITS; var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode; var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFLZW() { $this->MAX_LZW_BITS = 12; unSet($this->Next); unSet($this->Vals); unSet($this->Stack); unSet($this->Buf); $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1); $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1); $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1); $this->Buf = range(0, 279); } /////////////////////////////////////////////////////////////////////////// function deCompress($data, &$datLen) { $stLen = strlen($data); $datLen = 0; $ret = ""; // INITIALIZATION $this->LZWCommand($data, true); while(($iIndex = $this->LZWCommand($data, false)) >= 0) { $ret .= chr($iIndex); } $datLen = $stLen - strlen($data); if($iIndex != -2) { return false; } return $ret; } /////////////////////////////////////////////////////////////////////////// function LZWCommand(&$data, $bInit) { if($bInit) { $this->SetCodeSize = ord($data{0}); $data = substr($data, 1); $this->CodeSize = $this->SetCodeSize + 1; $this->ClearCode = 1 << $this->SetCodeSize; $this->EndCode = $this->ClearCode + 1; $this->MaxCode = $this->ClearCode + 2; $this->MaxCodeSize = $this->ClearCode << 1; $this->GetCode($data, $bInit); $this->Fresh = 1; for($i = 0; $i < $this->ClearCode; $i++) { $this->Next[$i] = 0; $this->Vals[$i] = $i; } for(; $i < (1 << $this->MAX_LZW_BITS); $i++) { $this->Next[$i] = 0; $this->Vals[$i] = 0; } $this->sp = 0; return 1; } if($this->Fresh) { $this->Fresh = 0; do { $this->FirstCode = $this->GetCode($data, $bInit); $this->OldCode = $this->FirstCode; } while($this->FirstCode == $this->ClearCode); return $this->FirstCode; } if($this->sp > 0) { $this->sp--; return $this->Stack[$this->sp]; } while(($Code = $this->GetCode($data, $bInit)) >= 0) { if($Code == $this->ClearCode) { for($i = 0; $i < $this->ClearCode; $i++) { $this->Next[$i] = 0; $this->Vals[$i] = $i; } for(; $i < (1 << $this->MAX_LZW_BITS); $i++) { $this->Next[$i] = 0; $this->Vals[$i] = 0; } $this->CodeSize = $this->SetCodeSize + 1; $this->MaxCodeSize = $this->ClearCode << 1; $this->MaxCode = $this->ClearCode + 2; $this->sp = 0; $this->FirstCode = $this->GetCode($data, $bInit); $this->OldCode = $this->FirstCode; return $this->FirstCode; } if($Code == $this->EndCode) { return -2; } $InCode = $Code; if($Code >= $this->MaxCode) { $this->Stack[$this->sp] = $this->FirstCode; $this->sp++; $Code = $this->OldCode; } while($Code >= $this->ClearCode) { $this->Stack[$this->sp] = $this->Vals[$Code]; $this->sp++; if($Code == $this->Next[$Code]) // Circular table entry, big GIF Error! return -1; $Code = $this->Next[$Code]; } $this->FirstCode = $this->Vals[$Code]; $this->Stack[$this->sp] = $this->FirstCode; $this->sp++; if(($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) { $this->Next[$Code] = $this->OldCode; $this->Vals[$Code] = $this->FirstCode; $this->MaxCode++; if(($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) { $this->MaxCodeSize *= 2; $this->CodeSize++; } } $this->OldCode = $InCode; if($this->sp > 0) { $this->sp--; return $this->Stack[$this->sp]; } } return $Code; } /////////////////////////////////////////////////////////////////////////// function GetCode(&$data, $bInit) { if($bInit) { $this->CurBit = 0; $this->LastBit = 0; $this->Done = 0; $this->LastByte = 2; return 1; } if(($this->CurBit + $this->CodeSize) >= $this->LastBit) { if($this->Done) { if($this->CurBit >= $this->LastBit) { // Ran off the end of my bits return 0; } return -1; } $this->Buf[0] = $this->Buf[$this->LastByte - 2]; $this->Buf[1] = $this->Buf[$this->LastByte - 1]; $Count = ord($data{0}); $data = substr($data, 1); if($Count) { for($i = 0; $i < $Count; $i++) { $this->Buf[2 + $i] = ord($data{$i}); } $data = substr($data, $Count); } else { $this->Done = 1; } $this->LastByte = 2 + $Count; $this->CurBit = ($this->CurBit - $this->LastBit) + 16; $this->LastBit = (2 + $Count) << 3; } $iRet = 0; for($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) { $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j; } $this->CurBit += $this->CodeSize; return $iRet; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFCOLORTABLE { var $m_nColors; var $m_arColors; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFCOLORTABLE() { unSet($this->m_nColors); unSet($this->m_arColors); } /////////////////////////////////////////////////////////////////////////// function load($lpData, $num) { $this->m_nColors = 0; $this->m_arColors = array(); for($i = 0; $i < $num; $i++) { $rgb = substr($lpData, $i * 3, 3); if(strlen($rgb) < 3) { return false; } $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0}); $this->m_nColors++; } return true; } /////////////////////////////////////////////////////////////////////////// function toString() { $ret = ""; for($i = 0; $i < $this->m_nColors; $i++) { $ret .= chr(($this->m_arColors[$i] & 0x000000FF)) . // R chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B } return $ret; } /////////////////////////////////////////////////////////////////////////// function toRGBQuad() { $ret = ""; for($i = 0; $i < $this->m_nColors; $i++) { $ret .= chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G chr(($this->m_arColors[$i] & 0x000000FF)) . // R "\x00"; } return $ret; } /////////////////////////////////////////////////////////////////////////// function colorIndex($rgb) { $rgb = intval($rgb) & 0xFFFFFF; $r1 = ($rgb & 0x0000FF); $g1 = ($rgb & 0x00FF00) >> 8; $b1 = ($rgb & 0xFF0000) >> 16; $idx = -1; for($i = 0; $i < $this->m_nColors; $i++) { $r2 = ($this->m_arColors[$i] & 0x000000FF); $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8; $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16; $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1); if(($idx == -1) || ($d < $dif)) { $idx = $i; $dif = $d; } } return $idx; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFFILEHEADER { var $m_lpVer; var $m_nWidth; var $m_nHeight; var $m_bGlobalClr; var $m_nColorRes; var $m_bSorted; var $m_nTableSize; var $m_nBgColor; var $m_nPixelRatio; var $m_colorTable; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFFILEHEADER() { unSet($this->m_lpVer); unSet($this->m_nWidth); unSet($this->m_nHeight); unSet($this->m_bGlobalClr); unSet($this->m_nColorRes); unSet($this->m_bSorted); unSet($this->m_nTableSize); unSet($this->m_nBgColor); unSet($this->m_nPixelRatio); unSet($this->m_colorTable); } /////////////////////////////////////////////////////////////////////////// function load($lpData, &$hdrLen) { $hdrLen = 0; $this->m_lpVer = substr($lpData, 0, 6); if(($this->m_lpVer <> "GIF87a") && ($this->m_lpVer <> "GIF89a")) { return false; } $this->m_nWidth = $this->w2i(substr($lpData, 6, 2)); $this->m_nHeight = $this->w2i(substr($lpData, 8, 2)); if(!$this->m_nWidth || !$this->m_nHeight) { return false; } $b = ord(substr($lpData, 10, 1)); $this->m_bGlobalClr = ($b & 0x80) ? true : false; $this->m_nColorRes = ($b & 0x70) >> 4; $this->m_bSorted = ($b & 0x08) ? true : false; $this->m_nTableSize = 2 << ($b & 0x07); $this->m_nBgColor = ord(substr($lpData, 11, 1)); $this->m_nPixelRatio = ord(substr($lpData, 12, 1)); $hdrLen = 13; if($this->m_bGlobalClr) { $this->m_colorTable = new CGIFCOLORTABLE(); if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) { return false; } $hdrLen += 3 * $this->m_nTableSize; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFIMAGEHEADER { var $m_nLeft; var $m_nTop; var $m_nWidth; var $m_nHeight; var $m_bLocalClr; var $m_bInterlace; var $m_bSorted; var $m_nTableSize; var $m_colorTable; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFIMAGEHEADER() { unSet($this->m_nLeft); unSet($this->m_nTop); unSet($this->m_nWidth); unSet($this->m_nHeight); unSet($this->m_bLocalClr); unSet($this->m_bInterlace); unSet($this->m_bSorted); unSet($this->m_nTableSize); unSet($this->m_colorTable); } /////////////////////////////////////////////////////////////////////////// function load($lpData, &$hdrLen) { $hdrLen = 0; $this->m_nLeft = $this->w2i(substr($lpData, 0, 2)); $this->m_nTop = $this->w2i(substr($lpData, 2, 2)); $this->m_nWidth = $this->w2i(substr($lpData, 4, 2)); $this->m_nHeight = $this->w2i(substr($lpData, 6, 2)); if(!$this->m_nWidth || !$this->m_nHeight) { return false; } $b = ord($lpData{8}); $this->m_bLocalClr = ($b & 0x80) ? true : false; $this->m_bInterlace = ($b & 0x40) ? true : false; $this->m_bSorted = ($b & 0x20) ? true : false; $this->m_nTableSize = 2 << ($b & 0x07); $hdrLen = 9; if($this->m_bLocalClr) { $this->m_colorTable = new CGIFCOLORTABLE(); if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) { return false; } $hdrLen += 3 * $this->m_nTableSize; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFIMAGE { var $m_disp; var $m_bUser; var $m_bTrans; var $m_nDelay; var $m_nTrans; var $m_lpComm; var $m_gih; var $m_data; var $m_lzw; /////////////////////////////////////////////////////////////////////////// function CGIFIMAGE() { unSet($this->m_disp); unSet($this->m_bUser); unSet($this->m_bTrans); unSet($this->m_nDelay); unSet($this->m_nTrans); unSet($this->m_lpComm); unSet($this->m_data); $this->m_gih = new CGIFIMAGEHEADER(); $this->m_lzw = new CGIFLZW(); } /////////////////////////////////////////////////////////////////////////// function load($data, &$datLen) { $datLen = 0; while(true) { $b = ord($data{0}); $data = substr($data, 1); $datLen++; switch($b) { case 0x21: // Extension $len = 0; if(!$this->skipExt($data, $len)) { return false; } $datLen += $len; break; case 0x2C: // Image // LOAD HEADER & COLOR TABLE $len = 0; if(!$this->m_gih->load($data, $len)) { return false; } $data = substr($data, $len); $datLen += $len; // ALLOC BUFFER $len = 0; if(!($this->m_data = $this->m_lzw->deCompress($data, $len))) { return false; } $data = substr($data, $len); $datLen += $len; if($this->m_gih->m_bInterlace) { $this->deInterlace(); } return true; case 0x3B: // EOF default: return false; } } return false; } /////////////////////////////////////////////////////////////////////////// function skipExt(&$data, &$extLen) { $extLen = 0; $b = ord($data{0}); $data = substr($data, 1); $extLen++; switch($b) { case 0xF9: // Graphic Control $b = ord($data{1}); $this->m_disp = ($b & 0x1C) >> 2; $this->m_bUser = ($b & 0x02) ? true : false; $this->m_bTrans = ($b & 0x01) ? true : false; $this->m_nDelay = $this->w2i(substr($data, 2, 2)); $this->m_nTrans = ord($data{4}); break; case 0xFE: // Comment $this->m_lpComm = substr($data, 1, ord($data{0})); break; case 0x01: // Plain text break; case 0xFF: // Application break; } // SKIP DEFAULT AS DEFS MAY CHANGE $b = ord($data{0}); $data = substr($data, 1); $extLen++; while($b > 0) { $data = substr($data, $b); $extLen += $b; $b = ord($data{0}); $data = substr($data, 1); $extLen++; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } /////////////////////////////////////////////////////////////////////////// function deInterlace() { $data = $this->m_data; for($i = 0; $i < 4; $i++) { switch($i) { case 0: $s = 8; $y = 0; break; case 1: $s = 8; $y = 4; break; case 2: $s = 4; $y = 2; break; case 3: $s = 2; $y = 1; break; } for(; $y < $this->m_gih->m_nHeight; $y += $s) { $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth); $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth); $data = substr($data, 0, $y * $this->m_gih->m_nWidth) . $lne . substr($data, ($y + 1) * $this->m_gih->m_nWidth); } } $this->m_data = $data; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIF { var $m_gfh; var $m_lpData; var $m_img; var $m_bLoaded; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIF() { $this->m_gfh = new CGIFFILEHEADER(); $this->m_img = new CGIFIMAGE(); $this->m_lpData = ""; $this->m_bLoaded = false; } /////////////////////////////////////////////////////////////////////////// function loadFile($lpszFileName, $iIndex) { if($iIndex < 0) { return false; } // READ FILE if(!($fh = @fOpen($lpszFileName, "rb"))) { return false; } //EDITEI - in order to read remote files (HTTP(s) and FTP protocols) if ( strpos($lpszFileName,"http") !== false or strpos($lpszFileName,"ftp") !== false ) { $contents = ''; while (!feof($fh)) $contents .= @fread($fh, 8192); } else { $contents = @fread($fh,@filesize($lpszFileName) ); } $this->m_lpData = $contents; // $this->m_lpData = @fRead($fh, @fileSize($lpszFileName)); fClose($fh); // GET FILE HEADER $len = 0; if(!$this->m_gfh->load($this->m_lpData, $len)) { return false; } $this->m_lpData = substr($this->m_lpData, $len); do { $imgLen = 0; if(!$this->m_img->load($this->m_lpData, $imgLen)) { return false; } $this->m_lpData = substr($this->m_lpData, $imgLen); } while($iIndex-- > 0); $this->m_bLoaded = true; return true; } /////////////////////////////////////////////////////////////////////////// function getSize($lpszFileName, &$width, &$height) { if(!($fh = @fOpen($lpszFileName, "rb"))) { return false; } $data = @fRead($fh, @fileSize($lpszFileName)); @fClose($fh); $gfh = new CGIFFILEHEADER(); $len = 0; if(!$gfh->load($data, $len)) { return false; } $width = $gfh->m_nWidth; $height = $gfh->m_nHeight; return true; } /////////////////////////////////////////////////////////////////////////// function getBmp($bgColor) { $out = ""; if(!$this->m_bLoaded) { return false; } // PREPARE COLOR TABLE (RGBQUADs) if($this->m_img->m_gih->m_bLocalClr) { $nColors = $this->m_img->m_gih->m_nTableSize; $rgbq = $this->m_img->m_gih->m_colorTable->toRGBQuad(); if($bgColor != -1) { $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor); } } else if($this->m_gfh->m_bGlobalClr) { $nColors = $this->m_gfh->m_nTableSize; $rgbq = $this->m_gfh->m_colorTable->toRGBQuad(); if($bgColor != -1) { $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor); } } else { $nColors = 0; $bgColor = -1; } // PREPARE BITMAP BITS $data = $this->m_img->m_data; $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth; $bmp = ""; $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0; for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) { for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) { if( ($x >= $this->m_img->m_gih->m_nLeft) && ($y >= $this->m_img->m_gih->m_nTop) && ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) && ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) { // PART OF IMAGE if($this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) { // TRANSPARENT -> BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } else { $bmp .= $data{$nPxl}; } } else { // BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } } $nPxl -= $this->m_gfh->m_nWidth << 1; // ADD PADDING for($x = 0; $x < $nPad; $x++) { $bmp .= "\x00"; } } // BITMAPFILEHEADER $out .= "BM"; $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp)); $out .= "\x00\x00"; $out .= "\x00\x00"; $out .= $this->dword(14 + 40 + ($nColors << 2)); // BITMAPINFOHEADER $out .= $this->dword(40); $out .= $this->dword($this->m_gfh->m_nWidth); $out .= $this->dword($this->m_gfh->m_nHeight); $out .= "\x01\x00"; $out .= "\x08\x00"; $out .= "\x00\x00\x00\x00"; $out .= "\x00\x00\x00\x00"; $out .= "\x12\x0B\x00\x00"; $out .= "\x12\x0B\x00\x00"; $out .= $this->dword($nColors % 256); $out .= "\x00\x00\x00\x00"; // COLOR TABLE if($nColors > 0) { $out .= $rgbq; } // DATA $out .= $bmp; return $out; } /////////////////////////////////////////////////////////////////////////// function getPng($bgColor) { $out = ""; if(!$this->m_bLoaded) { return false; } // PREPARE COLOR TABLE (RGBQUADs) if($this->m_img->m_gih->m_bLocalClr) { $nColors = $this->m_img->m_gih->m_nTableSize; $pal = $this->m_img->m_gih->m_colorTable->toString(); if($bgColor != -1) { $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor); } } else if($this->m_gfh->m_bGlobalClr) { $nColors = $this->m_gfh->m_nTableSize; $pal = $this->m_gfh->m_colorTable->toString(); if($bgColor != -1) { $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor); } } else { $nColors = 0; $bgColor = -1; } // PREPARE BITMAP BITS $data = $this->m_img->m_data; $nPxl = 0; $bmp = ""; for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) { $bmp .= "\x00"; for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) { if( ($x >= $this->m_img->m_gih->m_nLeft) && ($y >= $this->m_img->m_gih->m_nTop) && ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) && ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) { // PART OF IMAGE $bmp .= $data{$nPxl}; } else { // BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } } } $bmp = gzcompress($bmp, 9); /////////////////////////////////////////////////////////////////////// // SIGNATURE $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"; /////////////////////////////////////////////////////////////////////// // HEADER $out .= "\x00\x00\x00\x0D"; $tmp = "IHDR"; $tmp .= $this->ndword($this->m_gfh->m_nWidth); $tmp .= $this->ndword($this->m_gfh->m_nHeight); $tmp .= "\x08\x03\x00\x00\x00"; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); /////////////////////////////////////////////////////////////////////// // PALETTE if($nColors > 0) { $out .= $this->ndword($nColors * 3); $tmp = "PLTE"; $tmp .= $pal; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); } /////////////////////////////////////////////////////////////////////// // TRANSPARENCY if($this->m_img->m_bTrans && ($nColors > 0)) { $out .= $this->ndword($nColors); $tmp = "tRNS"; for($i = 0; $i < $nColors; $i++) { $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF"; } $out .= $tmp; $out .= $this->ndword(crc32($tmp)); } /////////////////////////////////////////////////////////////////////// // DATA BITS $out .= $this->ndword(strlen($bmp)); $tmp = "IDAT"; $tmp .= $bmp; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); /////////////////////////////////////////////////////////////////////// // END OF FILE $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82"; return $out; } /////////////////////////////////////////////////////////////////////////// function dword($val) { $val = intval($val); return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24); } /////////////////////////////////////////////////////////////////////////// function ndword($val) { $val = intval($val); return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF); } /////////////////////////////////////////////////////////////////////////// function width() { return $this->m_gfh->m_nWidth; } /////////////////////////////////////////////////////////////////////////// function height() { return $this->m_gfh->m_nHeight; } /////////////////////////////////////////////////////////////////////////// function comment() { return $this->m_img->m_lpComm; } /////////////////////////////////////////////////////////////////////////// function loaded() { return $this->m_bLoaded; } } /////////////////////////////////////////////////////////////////////////////////////////////////// ?>