<?php
/*
*------------------------------------------------------------
* ICO Image functions v2.0
*------------------------------------------------------------
* By JPEXS
*
* Function list:
* ImageCreateFromIco - Reads image from a ICO file
* ImageCreateFromExeIco - Reads image from icon in EXE file
* SaveExeIcon - Saves icon from the exe file
* ImageIco - Saves an image to icofile or writes it to output
*/
define("TRUE_COLOR", 0x1000000);
define("XP_COLOR", 4294967296);
define("MAX_COLOR", -2);
define("MAX_SIZE", -2);
/*
Version changes:
v2.0 - For icons with Alpha channel now you can set background color
- ImageCreateFromExeIco added
- Fixed MAX_SIZE and MAX_COLOR values
*/
/*
*------------------------------------------------------------
* ImageCreateFromIco
*------------------------------------------------------------
* - Reads image from a ICO file
*
* Parameters: $filename - Target ico file to load
* $icoColorCount - Icon color count (For multiple icons ico file)
* - 2,16,256, TRUE_COLOR or XP_COLOR
* $icoSize - Icon width (For multiple icons ico file)
* $AlphaBgR,$AlphaBgG,$AlphaBgB - Background color for alpha-channel images (Default is White)
* Returns: Image ID
*/
function ImageCreateFromIco($filename,$icoColorCount=16,$icoSize=16,$AlphaBgR=255,$AlphaBgG=255,$AlphaBgB=255)
{
$Ikona=GetIconsInfo($filename);
$IconID=-1;
$ColMax=-1;
$SizeMax=-1;
for($p=0;$p<count($Ikona);$p++)
{
$Ikona[$p]["NumberOfColors"]=pow(2,$Ikona[$p]["Info"]["BitsPerPixel"]);
};
for($p=0;$p<count($Ikona);$p++)
{
if(($ColMax==-1)or($Ikona[$p]["NumberOfColors"]>=$Ikona[$ColMax]["NumberOfColors"]))
if(($icoSize==$Ikona[$p]["Width"])or($icoSize==MAX_SIZE))
{
$ColMax=$p;
};
if(($SizeMax==-1)or($Ikona[$p]["Width"]>=$Ikona[$SizeMax]["Width"]))
if(($icoColorCount==$Ikona[$p]["NumberOfColors"])or($icoColorCount==MAX_COLOR))
{
$SizeMax=$p;
};
if($Ikona[$p]["NumberOfColors"]==$icoColorCount)
if($Ikona[$p]["Width"]==$icoSize)
{
$IconID=$p;
};
};
if($icoColorCount==MAX_COLOR) $IconID=$ColMax;
if($icoSize==MAX_SIZE) $IconID=$SizeMax;
$ColName=$icoColorCount;
if($icoSize==MAX_SIZE) $icoSize="Max";
if($ColName==TRUE_COLOR) $ColName="True";
if($ColName==XP_COLOR) $ColName="XP";
if($ColName==MAX_COLOR) $ColName="Max";
if($IconID==-1) die("Icon with $ColName colors and $icoSize x $icoSize size doesn't exist in this file!");
ReadIcon($filename,$IconID,$Ikona);
$biBitCount=$Ikona[$IconID]["Info"]["BitsPerPixel"];
if($Ikona[$IconID]["Info"]["BitsPerPixel"]==0)
{
$Ikona[$IconID]["Info"]["BitsPerPixel"]=24;
};
$biBitCount=$Ikona[$IconID]["Info"]["BitsPerPixel"];
if($biBitCount==0) $biBitCount=1;
$Ikona[$IconID]["BitCount"]=$Ikona[$IconID]["Info"]["BitsPerPixel"];
if($Ikona[$IconID]["BitCount"]>=24)
{
$img=imagecreatetruecolor($Ikona[$IconID]["Width"],$Ikona[$IconID]["Height"]);
if($Ikona[$IconID]["BitCount"]==32):
$backcolor=imagecolorallocate($img,$AlphaBgR,$AlphaBgG,$AlphaBgB);
imagefilledrectangle($img,0,0,$Ikona[$IconID]["Width"]-1,$Ikona[$IconID]["Height"]-1,$backcolor);
endif;
for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
{
$R=$Ikona[$IconID]["Data"][$x][$y]["r"];
$G=$Ikona[$IconID]["Data"][$x][$y]["g"];
$B=$Ikona[$IconID]["Data"][$x][$y]["b"];
if($Ikona[$IconID]["BitCount"]==32)
{
$Alpha=127-round($Ikona[$IconID]["Data"][$x][$y]["alpha"]*127/255);
if($Ikona[$IconID]["Maska"][$x][$y]==1) $Alpha=127;
$color=imagecolorexactalpha($img,$R,$G,$B,$Alpha);
if($color==-1) $color=imagecolorallocatealpha($img,$R,$G,$B,$Alpha);
}
else
{
$color=imagecolorexact($img,$R,$G,$B);
if($color==-1) $color=imagecolorallocate($img,$R,$G,$B);
};
imagesetpixel($img,$x,$y,$color);
};
}
else
{
$img=imagecreate($Ikona[$IconID]["Width"],$Ikona[$IconID]["Height"]);
for($p=0;$p<count($Ikona[$IconID]["Paleta"]);$p++)
$Paleta[$p]=imagecolorallocate($img,$Ikona[$IconID]["Paleta"][$p]["r"],$Ikona[$IconID]["Paleta"][$p]["g"],$Ikona[$IconID]["Paleta"][$p]["b"]);
for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
{
imagesetpixel($img,$x,$y,$Paleta[$Ikona[$IconID]["Data"][$x][$y]]);
};
};
$IsTransparent=false;
for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
if($Ikona[$IconID]["Maska"][$x][$y]==1)
{
$IsTransparent=true;
break;
};
if($Ikona[$IconID]["BitCount"]==32)
{
imagealphablending($img, false);
if(function_exists("imagesavealpha"))
imagesavealpha($img,true);
};
if($IsTransparent)
{
if(($Ikona[$IconID]["BitCount"]>=24)or(imagecolorstotal($img)>=256))
{
$img2=imagecreatetruecolor(imagesx($img),imagesy($img));
imagecopy($img2,$img,0,0,0,0,imagesx($img),imagesy($img));
imagedestroy($img);
$img=$img2;
imagetruecolortopalette($img,true,255);
};
$Pruhledna=imagecolorallocate($img,0,0,0);
for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
if($Ikona[$IconID]["Maska"][$x][$y]==1)
{
imagesetpixel($img,$x,$y,$Pruhledna);
};
imagecolortransparent($img,$Pruhledna);
};
return $img;
};
function ReadIcon($filename,$id,&$Ikona)
{
global $CurrentBit;
$f=fopen($filename,"rb");
fseek($f,6+$id*16);
$Width=freadbyte($f);
$Height=freadbyte($f);
fseek($f,6+$id*16+12);
$OffSet=freaddword($f);
fseek($f,$OffSet);
$p=$id;
$Ikona[$p]["Info"]["HeaderSize"]=freadlngint($f);
$Ikona[$p]["Info"]["ImageWidth"]=freadlngint($f);
$Ikona[$p]["Info"]["ImageHeight"]=freadlngint($f);
$Ikona[$p]["Info"]["NumberOfImagePlanes"]=freadword($f);
$Ikona[$p]["Info"]["BitsPerPixel"]=freadword($f);
$Ikona[$p]["Info"]["CompressionMethod"]=freadlngint($f);
$Ikona[$p]["Info"]["SizeOfBitmap"]=freadlngint($f);
$Ikona[$p]["Info"]["HorzResolution"]=freadlngint($f);
$Ikona[$p]["Info"]["VertResolution"]=freadlngint($f);
$Ikona[$p]["Info"]["NumColorUsed"]=freadlngint($f);
$Ikona[$p]["Info"]["NumSignificantColors"]=freadlngint($f);
$biBitCount=$Ikona[$p]["Info"]["BitsPerPixel"];
if($Ikona[$p]["Info"]["BitsPerPixel"]<=8)
{
$barev=pow(2,$biBitCount);
for($b=0;$b<$barev;$b++)
{
$Ikona[$p]["Paleta"][$b]["b"]=freadbyte($f);
$Ikona[$p]["Paleta"][$b]["g"]=freadbyte($f);
$Ikona[$p]["Paleta"][$b]["r"]=freadbyte($f);
freadbyte($f);
};
$Zbytek=(4-ceil(($Width/(8/$biBitCount)))%4)%4;
for($y=$Height-1;$y>=0;$y--)
{
$CurrentBit=0;
for($x=0;$x<$Width;$x++)
{
$C=freadbits($f,$biBitCount);
$Ikona[$p]["Data"][$x][$y]=$C;
};
if($CurrentBit!=0) {freadbyte($f);};
for($g=0;$g<$Zbytek;$g++)
freadbyte($f);
};
}
elseif($biBitCount==24)
{
$Zbytek=$Width%4;
for($y=$Height-1;$y>=0;$y--)
{
for($x=0;$x<$Width;$x++)
{
$B=freadbyte($f);
$G=freadbyte($f);
$R=freadbyte($f);
$Ikona[$p]["Data"][$x][$y]["r"]=$R;
$Ikona[$p]["Data"][$x][$y]["g"]=$G;
$Ikona[$p]["Data"][$x][$y]["b"]=$B;
}
for($z=0;$z<$Zbytek;$z++)
freadbyte($f);
};
}
elseif($biBitCount==32)
{
$Zbytek=$Width%4;
for($y=$Height-1;$y>=0;$y--)
{
for($x=0;$x<$Width;$x++)
{
$B=freadbyte($f);
$G=freadbyte($f);
$R=freadbyte($f);
$Alpha=freadbyte($f);
$Ikona[$p]["Data"][$x][$y]["r"]=$R;
$Ikona[$p]["Data"][$x][$y]["g"]=$G;
$Ikona[$p]["Data"][$x][$y]["b"]=$B;
$Ikona[$p]["Data"][$x][$y]["alpha"]=$Alpha;
}
for($z=0;$z<$Zbytek;$z++)
freadbyte($f);
};
};
//Maska
$Zbytek=(4-ceil(($Width/(8)))%4)%4;
for($y=$Height-1;$y>=0;$y--)
{
$CurrentBit=0;
for($x=0;$x<$Width;$x++)
{
$C=freadbits($f,1);
$Ikona[$p]["Maska"][$x][$y]=$C;
};
if($CurrentBit!=0) {freadbyte($f);};
for($g=0;$g<$Zbytek;$g++)
freadbyte($f);
};
//--------------
fclose($f);
};
function GetIconsInfo($filename)
{
global $CurrentBit;
$f=fopen($filename,"rb");
$Reserved=freadword($f);
$Type=freadword($f);
$Count=freadword($f);
for($p=0;$p<$Count;$p++)
{
$Ikona[$p]["Width"]=freadbyte($f);
$Ikona[$p]["Height"]=freadbyte($f);
$Ikona[$p]["ColorCount"]=freadword($f);
if($Ikona[$p]["ColorCount"]==0) $Ikona[$p]["ColorCount"]=256;
$Ikona[$p]["Planes"]=freadword($f);
$Ikona[$p]["BitCount"]=freadword($f);
$Ikona[$p]["BytesInRes"]=freaddword($f);
$Ikona[$p]["ImageOffset"]=freaddword($f);
};
if(!feof($f)):
for($p=0;$p<$Count;$p++)
{
fseek($f,$Ikona[$p]["ImageOffset"]+14);
$Ikona[$p]["Info"]["BitsPerPixel"]=freadword($f);
};
endif;
fclose($f);
return $Ikona;
};
/*
*------------------------------------------------------------
* ImageCreateFromExeIco
*------------------------------------------------------------
* - Reads image from a icon in exe file
*
* Parameters: $filename - Target exefile
* $icoIndex - Index of the icon in exefile
* $icoColorCount - Icon color count (For multiple icons ico file)
* - 2,16,256, TRUE_COLOR or XP_COLOR
* $icoSize - Icon width (For multiple icons ico file)
* $AlphaBgR,$AlphaBgG,$AlphaBgB - Background color for alpha-channel images (Default is White)
* Returns: Image ID or empty string if failed
*/
function ImageCreateFromExeIco($filename,$icoIndex,$icoColorCount=16,$icoSize=16,$AlphaBgR=255,$AlphaBgG=255,$AlphaBgB=255)
{
$ok=SaveExeIcon($filename,"icotemp.dat",$icoIndex);
if(!$ok):
$im="";
else:
$im=ImageCreateFromIco("icotemp.dat",$icoColorCount,$icoSize,$AlphaBgR,$AlphaBgG,$AlphaBgB);
unlink("icotemp.dat");
endif;
return $im;
};
/*
*------------------------------------------------------------
* SaveExeIcon
*------------------------------------------------------------
* - Saves icon from the exe file
*
* Parameters: $filename - Target exefile
* $icoFileNameOrPath - Filename to save ico or path (Default "")
* (path if you want more than 1 icon)
* (If "", the filename is "$icoIndex.ico")
*
* $icoIndex - Index(es) of the icon in exefile (Default -1)
* (If -1, all icons are saved)
* (Can be an array of indexes!)
*/
function SaveExeIcon($filename,$icoFileNameOrPath="",$iconIndex=-1/*-1 for all,or can be array*/)
{
global $f,$StartOfRsrc,$ImageBase,$ResVirtualAddress;
$f=fopen($filename,"r");
$MZ=fread($f,2);
if($MZ!="MZ") NotValidExe();
fseek($f,60);
$OffsetToNewHeader=freaddword($f);
fseek($f,$OffsetToNewHeader);
$PE=fread($f,2);
if($PE!="PE") NotValidExe();
fread($f,4);
$NumberOfSections=freadword($f);
fseek($f,ftell($f)+12);
$SizeOfOptionalHeader=freadword($f);
$PosMagic=ftell($f)+2;
fseek($f,$PosMagic+$SizeOfOptionalHeader);
for($p=0;$p<$NumberOfSections;$p++):
$SectionName[$p]=trim(fread($f,8));
$VirtualSize[$p]=freaddword($f);
$VirtualAddress[$p]=freaddword($f);
$PhysicalSize[$p]=freaddword($f);
$PhysicalOffset[$p]=freaddword($f);
fread($f,16);
if($SectionName[$p]==".rsrc"):
$ResVirtualAddress=$VirtualAddress[$p];
fseek($f,$PhysicalOffset[$p]);
$StartOfRsrc=$PhysicalOffset[$p];
ReadResDirectoryEntry($R,$PhysicalOffset[$p]);
$IconCount=null;
$Ikona=null;
while (list ($key, $val) = each ($R["Subdir"])):
if($key==14):
$r=0;
while (list ($key2, $val2) = each ($R["Subdir"][$key]["Subdir"])):
while (list ($key3, $val3) = each ($R["Subdir"][$key]["Subdir"][$key2]["Subdir"])):
fseek($f,$val3["DataOffset"]);
$Reserved=freadword($f);
$Type=freadword($f);
$ic=freadword($f);
$IconCount[]=$ic;
for($s=0;$s<$ic;$s++)
{
$Ikona[$r][$s]["Width"]=freadbyte($f);
$Ikona[$r][$s]["Height"]=freadbyte($f);
$Ikona[$r][$s]["ColorCount"]=freadword($f);
$Ikona[$r][$s]["Planes"]=freadword($f);
$Ikona[$r][$s]["BitCount"]=freadword($f);
$Ikona[$r][$s]["BytesInRes"]=freaddword($f);
$Ikona[$r][$s]["IconId"]=freadword($f);
};
fseek($f,$val3["DataOffset"]);
$r++;
endwhile;
endwhile;
endif;
endwhile;
reset ($R["Subdir"]);
while (list ($key, $val) = each ($R["Subdir"])):
if($key==3):
while (list ($key2, $val2) = each ($R["Subdir"][$key]["Subdir"])):
for($r=0;$r<count($Ikona);$r++):
for($s=0;$s<count($Ikona[$r]);$s++):
while (list ($key3, $val3) = each ($R["Subdir"][$key]["Subdir"][$Ikona[$r][$s]["IconId"]]["Subdir"])):
if(($iconIndex==$r)or($iconIndex==-1)or((is_array($iconIndex))and(in_array($r,$iconIndex)))):
fseek($f,$val3["DataOffset"]);
$Ikona[$r][$s]["Data"]=fread($f,$val3["DataSize"]);
$Ikona[$r][$s]["DataSize"]=$val3["DataSize"];
endif;
endwhile;
endfor;
endfor;
endwhile;
endif;
endwhile;
$ok=false;
for($r=0;$r<count($Ikona);$r++):
if(($iconIndex==$r)or($iconIndex==-1)or((is_array($iconIndex))and(in_array($r,$iconIndex)))):
$savefile=$icoFileNameOrPath;
if($icoFileNameOrPath=="")
{
$savefile="$r.ico";
}
else
{
if(($iconIndex==-1)or(is_array($iconIndex)))
$savefile=$icoFileNameOrPath."$r.ico";
};
$f2=fopen($savefile,"w");
fwrite($f2,inttoword(0));
fwrite($f2,inttoword(1));
fwrite($f2,inttoword(count($Ikona[$r])));
$Offset=6+16*count($Ikona[$r]);
for($s=0;$s<count($Ikona[$r]);$s++):
fwrite($f2,inttobyte($Ikona[$r][$s]["Width"]));
fwrite($f2,inttobyte($Ikona[$r][$s]["Height"]));
fwrite($f2,inttoword($Ikona[$r][$s]["ColorCount"]));
fwrite($f2,inttoword($Ikona[$r][$s]["Planes"]));
fwrite($f2,inttoword($Ikona[$r][$s]["BitCount"]));
fwrite($f2,inttodword($Ikona[$r][$s]["BytesInRes"]));
fwrite($f2,inttodword($Offset));
$Offset+=$Ikona[$r][$s]["DataSize"];
endfor;
for($s=0;$s<count($Ikona[$r]);$s++):
fwrite($f2,$Ikona[$r][$s]["Data"]);
endfor;
fclose($f2);
$ok=true;
endif;
endfor;
return $ok;
endif;
endfor;
fclose($f);
};
function ReadResDirectoryEntry(&$parentRes,$offset)
{
global $f,$StartOfRsrc,$ImageBase,$ResVirtualAddress;
$lastPos=ftell($f);
$Res=null;
fseek($f,$offset);
//IMAGE_RESOURCE_DIRECTORY
$Characteristics=freaddword($f);
$TimeDateStamp=freaddword($f);
$MajorVersion=freadword($f);
$MinorVersion=freadword($f);
$NumberOfNamedEntries=freadword($f);
$NumberOfIdEntries=freadword($f);
for($q=0;$q<$NumberOfNamedEntries+$NumberOfIdEntries;$q++):
//IMAGE_RESOURCE_DIRECTORY_ENTRY
$ResName=freaddword($f);
$lastPos2=ftell($f);
if($ResName>=0x80000000):
//String Name
$ResNameOffset=$ResName-0x80000000;
fseek($f,$StartOfRsrc+$ResNameOffset);
$StringLength=freadword($f);
$Identificator=(fread($f,$StringLength*2));
fseek($f,$lastPos2);
else:
//Integer Id
$Identificator=$ResName;
endif;
$ResOffsetToData=freaddword($f);
if($ResOffsetToData>=0x80000000):
$SubResOffset=$ResOffsetToData-0x80000000;
ReadResDirectoryEntry($Res["$Identificator"],$StartOfRsrc+$SubResOffset);
else:
$RawDataOffset=$ResOffsetToData;
$lastPos2=ftell($f);
fseek($f,$StartOfRsrc+$RawDataOffset);
//IMAGE_RESOURCE_DATA_ENTRY
$OffsetToData=freaddword($f);
$Res["$Identificator"]["DataOffset"]=$StartOfRsrc-$ResVirtualAddress+$OffsetToData;
$Res["$Identificator"]["DataSize"]=freaddword($f);
$CodePage=freaddword($f);
$Reserved=freaddword($f);
fseek($f,$lastPos2);
endif;
endfor;
fseek($f,$lastPos);
$parentRes["Subdir"]=$Res;
};
//------------------------
/*
*------------------------------------------------------------
* ImageIco
*------------------------------------------------------------
* - Returns ICO file
*
* Parameters: $img - Target Image (Can be array of images)
* $filename - Target ico file to save
*
*
* Note: For returning icons to Browser, you have to set header:
*
* header("Content-type: image/x-icon");
*
*/
function ImageIco($Images/*image or image array*/,$filename="")
{
if(is_array($Images))
{
$ImageCount=count($Images);
$Image=$Images;
}
else
{
$Image[0]=$Images;
$ImageCount=1;
};
$WriteToFile=false;
if($filename!="")
{
$WriteToFile=true;
};
$ret="";
$ret.=inttoword(0); //PASSWORD
$ret.=inttoword(1); //SOURCE
$ret.=inttoword($ImageCount); //ICONCOUNT
for($q=0;$q<$ImageCount;$q++)
{
$img=$Image[$q];
$Width=imagesx($img);
$Height=imagesy($img);
$ColorCount=imagecolorstotal($img);
$Transparent=imagecolortransparent($img);
$IsTransparent=$Transparent!=-1;
if($IsTransparent) $ColorCount--;
if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
//ICONINFO:
$ret.=inttobyte($Width);//
$ret.=inttobyte($Height);//
$ret.=inttobyte($ColorCount);//
$ret.=inttobyte(0);//RESERVED
$Planes=0;
if($BitCount>=8) $Planes=1;
$ret.=inttoword($f,$Planes);//PLANES
if($BitCount>=8) $WBitCount=$BitCount;
if($BitCount==4) $WBitCount=0;
if($BitCount==1) $WBitCount=0;
$ret.=inttoword($WBitCount);//BITS
$Zbytek=(4-($Width/(8/$BitCount))%4)%4;
$ZbytekMask=(4-($Width/8)%4)%4;
$PalSize=0;
$Size=40+($Width/(8/$BitCount)+$Zbytek)*$Height+(($Width/8+$ZbytekMask) * $Height);
if($BitCount<24)
$Size+=pow(2,$BitCount)*4;
$IconId=1;
$ret.=inttodword($Size); //SIZE
$OffSet=6+16*$ImageCount+$FullSize;
$ret.=inttodword(6+16*$ImageCount+$FullSize);//OFFSET
$FullSize+=$Size;
//-------------
};
for($q=0;$q<$ImageCount;$q++)
{
$img=$Image[$q];
$Width=imagesx($img);
$Height=imagesy($img);
$ColorCount=imagecolorstotal($img);
$Transparent=imagecolortransparent($img);
$IsTransparent=$Transparent!=-1;
if($IsTransparent) $ColorCount--;
if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
//ICONS
$ret.=inttodword(40);//HEADSIZE
$ret.=inttodword($Width);//
$ret.=inttodword(2*$Height);//
$ret.=inttoword(1); //PLANES
$ret.=inttoword($BitCount); //
$ret.=inttodword(0);//Compress method
$ZbytekMask=($Width/8)%4;
$Zbytek=($Width/(8/$BitCount))%4;
$Size=($Width/(8/$BitCount)+$Zbytek)*$Height+(($Width/8+$ZbytekMask) * $Height);
$ret.=inttodword($Size);//SIZE
$ret.=inttodword(0);//HPIXEL_M
$ret.=inttodword(0);//V_PIXEL_M
$ret.=inttodword($ColorCount); //UCOLORS
$ret.=inttodword(0); //DCOLORS
//---------------
$CC=$ColorCount;
if($CC==0) $CC=256;
if($BitCount<24)
{
$ColorTotal=imagecolorstotal($img);
if($IsTransparent) $ColorTotal--;
for($p=0;$p<$ColorTotal;$p++)
{
$color=imagecolorsforindex($img,$p);
$ret.=inttobyte($color["blue"]);
$ret.=inttobyte($color["green"]);
$ret.=inttobyte($color["red"]);
$ret.=inttobyte(0); //RESERVED
};
$CT=$ColorTotal;
for($p=$ColorTotal;$p<$CC;$p++)
{
$ret.=inttobyte(0);
$ret.=inttobyte(0);
$ret.=inttobyte(0);
$ret.=inttobyte(0); //RESERVED
};
};
if($BitCount<=8)
{
for($y=$Height-1;$y>=0;$y--)
{
$bWrite="";
for($x=0;$x<$Width;$x++)
{
$color=imagecolorat($img,$x,$y);
if($color==$Transparent)
$color=imagecolorexact($img,0,0,0);
if($color==-1) $color=0;
if($color>pow(2,$BitCount)-1) $color=0;
$bWrite.=decbinx($color,$BitCount);
if(strlen($bWrite)==8)
{
$ret.=inttobyte(bindec($bWrite));
$bWrite="";
};
};
if((strlen($bWrite)<8)and(strlen($bWrite)!=0))
{
$sl=strlen($bWrite);
for($t=0;$t<8-$sl;$t++)
$sl.="0";
$ret.=inttobyte(bindec($bWrite));
};
for($z=0;$z<$Zbytek;$z++)
$ret.=inttobyte(0);
};
};
if($BitCount>=24)
{
for($y=$Height-1;$y>=0;$y--)
{
for($x=0;$x<$Width;$x++)
{
$color=imagecolorsforindex($img,imagecolorat($img,$x,$y));
$ret.=inttobyte($color["blue"]);
$ret.=inttobyte($color["green"]);
$ret.=inttobyte($color["red"]);
if($BitCount==32)
$ret.=inttobyte(0);//Alpha for XP_COLORS
};
for($z=0;$z<$Zbytek;$z++)
$ret.=inttobyte(0);
};
};
//MASK
for($y=$Height-1;$y>=0;$y--)
{
$byteCount=0;
$bOut="";
for($x=0;$x<$Width;$x++)
{
if(($Transparent!=-1)and(imagecolorat($img,$x,$y)==$Transparent))
{
$bOut.="1";
}
else
{
$bOut.="0";
};
};
for($p=0;$p<strlen($bOut);$p+=8)
{
$byte=bindec(substr($bOut,$p,8));
$byteCount++;
$ret.=inttobyte($byte);
};
$Zbytek=$byteCount%4;
for($z=0;$z<$Zbytek;$z++)
{
$ret.=inttobyte(0xff);
};
};
//------------------
};//q
if($WriteToFile)
{
$f=fopen($filename,"w");
fwrite($f,$ret);
fclose($f);
}
else
{
echo $ret;
};
};
/*
* Helping functions:
*-------------------------
*
* inttobyte($n) - returns chr(n)
* inttodword($n) - returns dword (n)
* inttoword($n) - returns word(n)
* freadbyte($file) - reads 1 byte from $file
* freadword($file) - reads 2 bytes (1 word) from $file
* freaddword($file) - reads 4 bytes (1 dword) from $file
* freadlngint($file) - same as freaddword($file)
* decbin8($d) - returns binary string of d zero filled to 8
* RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte
* freadbits($file,$count) - reads next $count bits from $file
*/
function decbin8($d)
{
return decbinx($d,8);
};
function decbinx($d,$n)
{
$bin=decbin($d);
$sbin=strlen($bin);
for($j=0;$j<$n-$sbin;$j++)
$bin="0$bin";
return $bin;
};
function RetBits($byte,$start,$len)
{
$bin=decbin8($byte);
$r=bindec(substr($bin,$start,$len));
return $r;
};
$CurrentBit=0;
function freadbits($f,$count)
{
global $CurrentBit,$SMode;
$Byte=freadbyte($f);
$LastCBit=$CurrentBit;
$CurrentBit+=$count;
if($CurrentBit==8)
{
$CurrentBit=0;
}
else
{
fseek($f,ftell($f)-1);
};
return RetBits($Byte,$LastCBit,$count);
};
function freadbyte($f)
{
return ord(fread($f,1));
};
function freadword($f)
{
$b1=freadbyte($f);
$b2=freadbyte($f);
return $b2*256+$b1;
};
function freadlngint($f)
{
return freaddword($f);
};
function freaddword($f)
{
$b1=freadword($f);
$b2=freadword($f);
return $b2*65536+$b1;
};
function inttobyte($n)
{
return chr($n);
};
function inttodword($n)
{
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
};
function inttoword($n)
{
return chr($n & 255).chr(($n >> 8) & 255);
};
?>