WordPress.org

Make WordPress Core

Ticket #16434: ico2_3.php

File ico2_3.php, 26.9 KB (added by brandondove, 2 years ago)

GPLv2 version of ImageICO php lib

Line 
1<?php
2/**
3 * @package com.jpexs.image.ico
4 *
5 * JPEXS ICO Image functions
6 * @version 2.3
7 * @author JPEXS
8 * @copyright (c) JPEXS 2004-2012
9 *
10 * Webpage: http://www.jpexs.com
11 * Email: jpexs@jpexs.com
12 *
13 * If you like my script, you can donate... visit my webpages or email me for more info.
14 *
15 *        Version changes:
16 *          2012-02-25 v2.3 - License changed to GNU/GPL v2 or v3
17 *          2012-02-18 v2.2 - License changed to GNU/GPL v3
18 *          2009-02-23 v2.1 - redesigned sourcecode, phpdoc included, all internal functions and global variables have prefix "jpexs_"
19 *                     v2.0 - For icons with Alpha channel now you can set background color
20 *                          - ImageCreateFromExeIco added
21 *                          - Fixed ICO_MAX_SIZE and ICO_MAX_COLOR values
22 *
23 * TODO list:
24 *      - better error handling
25 *      - better internal function handling
26 *      - class encapsulation
27 *
28 * License:
29 *  This program is free software: you can redistribute it and/or modify
30 *  it under the terms of the GNU General Public License as published by
31 *  the Free Software Foundation, either version 2 or version 3 of the License, or
32 *  (at your option) any later version.
33 *
34 *  This program is distributed in the hope that it will be useful,
35 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
36 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37 *  GNU General Public License for more details.
38 *
39 *  You should have received a copy of the GNU General Public License
40 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
41 */
42
43/** TrueColor images constant  */
44define("ICO_TRUE_COLOR", 0x1000000);
45/** XPColor images constant (Alpha channel) */
46define("ICO_XP_COLOR", 4294967296);
47/** Image with maximum colors */
48define("ICO_MAX_COLOR", -2);
49/** Image with maximal size */
50define("ICO_MAX_SIZE", -2);
51
52
53/** TrueColor images constant
54 * @deprecated Deprecated since version 2.1, please use ICO_ constants
55 */
56define("TRUE_COLOR", 0x1000000);
57/** XPColor images constant (Alpha channel)
58 * @deprecated Deprecated since version 2.1, please use ICO_ constants
59 */
60define("XP_COLOR", 4294967296);
61/** Image with maximum colors
62 * @deprecated Deprecated since version 2.1, please use ICO_ constants
63 */
64define("MAX_COLOR", -2);
65/** Image with maximal size
66 * @deprecated Deprecated since version 2.1, please use ICO_ constants
67 */
68define("MAX_SIZE", -2);
69
70
71/**
72 * Reads image from a ICO file
73 *
74 * @param string $filename Target ico file to load
75 * @param int $icoColorCount Icon color count (For multiple icons ico file) - 2,16,256, ICO_TRUE_COLOR, ICO_XP_COLOR or ICO_MAX_COLOR
76 * @param int $icoSize Icon width (For multiple icons ico file) or ICO_MAX_SIZE
77 * @param int $alphaBgR Background color R value for alpha-channel images (Default is White)
78 * @param int $alphaBgG Background color G value for alpha-channel images (Default is White)
79 * @param int $alphaBgB Background color B value for alpha-channel images (Default is White)
80 * @return resource Image resource
81 */
82function imageCreateFromIco($filename,$icoColorCount=16,$icoSize=16,$alphaBgR=255,$alphaBgG=255,$alphaBgB=255)
83{
84$Ikona=jpexs_GetIconsInfo($filename);
85
86$IconID=-1;
87
88$ColMax=-1;
89$SizeMax=-1;
90
91for($p=0;$p<count($Ikona);$p++)
92{
93$Ikona[$p]["NumberOfColors"]=pow(2,$Ikona[$p]["Info"]["BitsPerPixel"]);
94};
95
96
97for($p=0;$p<count($Ikona);$p++)
98{
99
100if(($ColMax==-1)or($Ikona[$p]["NumberOfColors"]>=$Ikona[$ColMax]["NumberOfColors"]))
101if(($icoSize==$Ikona[$p]["Width"])or($icoSize==ICO_MAX_SIZE))
102 {
103  $ColMax=$p;
104 };
105
106if(($SizeMax==-1)or($Ikona[$p]["Width"]>=$Ikona[$SizeMax]["Width"]))
107if(($icoColorCount==$Ikona[$p]["NumberOfColors"])or($icoColorCount==ICO_MAX_COLOR))
108 {
109   $SizeMax=$p;
110 };
111
112
113if($Ikona[$p]["NumberOfColors"]==$icoColorCount)
114if($Ikona[$p]["Width"]==$icoSize)
115 {
116
117 $IconID=$p;
118 };
119};
120
121  if($icoColorCount==ICO_MAX_COLOR) $IconID=$ColMax;
122  if($icoSize==ICO_MAX_SIZE) $IconID=$SizeMax;
123
124$ColName=$icoColorCount;
125
126if($icoSize==ICO_MAX_SIZE) $icoSize="Max";
127if($ColName==ICO_TRUE_COLOR) $ColName="True";
128if($ColName==ICO_XP_COLOR) $ColName="XP";
129if($ColName==ICO_MAX_COLOR) $ColName="Max";
130if($IconID==-1) die("Icon with $ColName colors and $icoSize x $icoSize size doesn't exist in this file!");
131
132
133jpexs_readIcon($filename,$IconID,$Ikona);
134
135 $biBitCount=$Ikona[$IconID]["Info"]["BitsPerPixel"];
136
137
138  if($Ikona[$IconID]["Info"]["BitsPerPixel"]==0)
139  {
140  $Ikona[$IconID]["Info"]["BitsPerPixel"]=24;
141  };
142
143 $biBitCount=$Ikona[$IconID]["Info"]["BitsPerPixel"];
144 if($biBitCount==0) $biBitCount=1;
145
146
147$Ikona[$IconID]["BitCount"]=$Ikona[$IconID]["Info"]["BitsPerPixel"];
148
149
150
151if($Ikona[$IconID]["BitCount"]>=24)
152{
153$img=imagecreatetruecolor($Ikona[$IconID]["Width"],$Ikona[$IconID]["Height"]);
154if($Ikona[$IconID]["BitCount"]==32):
155  $backcolor=imagecolorallocate($img,$alphaBgR,$alphaBgG,$alphaBgB);
156  imagefilledrectangle($img,0,0,$Ikona[$IconID]["Width"]-1,$Ikona[$IconID]["Height"]-1,$backcolor);
157endif;
158for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
159for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
160 {
161 $R=$Ikona[$IconID]["Data"][$x][$y]["r"];
162 $G=$Ikona[$IconID]["Data"][$x][$y]["g"];
163 $B=$Ikona[$IconID]["Data"][$x][$y]["b"];
164 if($Ikona[$IconID]["BitCount"]==32)
165 {
166 $Alpha=127-round($Ikona[$IconID]["Data"][$x][$y]["alpha"]*127/255);
167 if($Ikona[$IconID]["Maska"][$x][$y]==1) $Alpha=127;
168 $color=imagecolorexactalpha($img,$R,$G,$B,$Alpha);
169 if($color==-1) $color=imagecolorallocatealpha($img,$R,$G,$B,$Alpha);
170 }
171 else
172 {
173 $color=imagecolorexact($img,$R,$G,$B);
174 if($color==-1) $color=imagecolorallocate($img,$R,$G,$B);
175 };
176
177 imagesetpixel($img,$x,$y,$color);
178
179 };
180
181}
182else
183{
184$img=imagecreate($Ikona[$IconID]["Width"],$Ikona[$IconID]["Height"]);
185for($p=0;$p<count($Ikona[$IconID]["Paleta"]);$p++)
186 $Paleta[$p]=imagecolorallocate($img,$Ikona[$IconID]["Paleta"][$p]["r"],$Ikona[$IconID]["Paleta"][$p]["g"],$Ikona[$IconID]["Paleta"][$p]["b"]);
187
188for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
189for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
190 {
191 imagesetpixel($img,$x,$y,$Paleta[$Ikona[$IconID]["Data"][$x][$y]]);
192 };
193};
194$IsTransparent=false; 
195for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
196for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
197 if($Ikona[$IconID]["Maska"][$x][$y]==1)
198  {
199   $IsTransparent=true;
200   break;
201  };
202if($Ikona[$IconID]["BitCount"]==32)
203{
204 imagealphablending($img, false);
205 if(function_exists("imagesavealpha"))
206  imagesavealpha($img,true);
207};
208
209if($IsTransparent)
210 {
211  if(($Ikona[$IconID]["BitCount"]>=24)or(imagecolorstotal($img)>=256))
212   {
213   $img2=imagecreatetruecolor(imagesx($img),imagesy($img));
214   imagecopy($img2,$img,0,0,0,0,imagesx($img),imagesy($img));
215   imagedestroy($img);
216   $img=$img2;
217   imagetruecolortopalette($img,true,255);
218
219   };
220    $Pruhledna=imagecolorallocate($img,0,0,0);
221    for($y=0;$y<$Ikona[$IconID]["Height"];$y++)
222     for($x=0;$x<$Ikona[$IconID]["Width"];$x++)
223      if($Ikona[$IconID]["Maska"][$x][$y]==1)
224       {
225        imagesetpixel($img,$x,$y,$Pruhledna);
226       };
227  imagecolortransparent($img,$Pruhledna);
228 };
229
230return $img;
231
232
233};
234
235
236
237
238function jpexs_readIcon($filename,$id,&$Ikona)
239{
240global $jpexs_currentBit;
241
242$f=fopen($filename,"rb");
243
244fseek($f,6+$id*16);
245  $Width=jpexs_freadbyte($f);
246  $Height=jpexs_freadbyte($f);
247fseek($f,6+$id*16+12);
248$OffSet=jpexs_freaddword($f);
249fseek($f,$OffSet);
250
251$p=$id;
252
253  $Ikona[$p]["Info"]["HeaderSize"]=jpexs_freadlngint($f);
254  $Ikona[$p]["Info"]["ImageWidth"]=jpexs_freadlngint($f);
255  $Ikona[$p]["Info"]["ImageHeight"]=jpexs_freadlngint($f);
256  $Ikona[$p]["Info"]["NumberOfImagePlanes"]=jpexs_freadword($f);
257  $Ikona[$p]["Info"]["BitsPerPixel"]=jpexs_freadword($f);
258  $Ikona[$p]["Info"]["CompressionMethod"]=jpexs_freadlngint($f);
259  $Ikona[$p]["Info"]["SizeOfBitmap"]=jpexs_freadlngint($f);
260  $Ikona[$p]["Info"]["HorzResolution"]=jpexs_freadlngint($f);
261  $Ikona[$p]["Info"]["VertResolution"]=jpexs_freadlngint($f);
262  $Ikona[$p]["Info"]["NumColorUsed"]=jpexs_freadlngint($f);
263  $Ikona[$p]["Info"]["NumSignificantColors"]=jpexs_freadlngint($f);
264
265
266 $biBitCount=$Ikona[$p]["Info"]["BitsPerPixel"];
267
268 if($Ikona[$p]["Info"]["BitsPerPixel"]<=8)
269  {
270
271 $barev=pow(2,$biBitCount);
272
273  for($b=0;$b<$barev;$b++)
274    {
275    $Ikona[$p]["Paleta"][$b]["b"]=jpexs_freadbyte($f);
276    $Ikona[$p]["Paleta"][$b]["g"]=jpexs_freadbyte($f);
277    $Ikona[$p]["Paleta"][$b]["r"]=jpexs_freadbyte($f);
278    jpexs_freadbyte($f);
279    };
280
281$Zbytek=(4-ceil(($Width/(8/$biBitCount)))%4)%4;
282
283
284for($y=$Height-1;$y>=0;$y--)
285    {
286     $jpexs_currentBit=0;
287     for($x=0;$x<$Width;$x++)
288      {
289         $C=jpexs_freadbits($f,$biBitCount);
290         $Ikona[$p]["Data"][$x][$y]=$C;
291      };
292
293    if($jpexs_currentBit!=0) {jpexs_freadbyte($f);};
294    for($g=0;$g<$Zbytek;$g++)
295     jpexs_freadbyte($f);
296     };
297
298}
299elseif($biBitCount==24)
300{
301 $Zbytek=$Width%4;
302
303   for($y=$Height-1;$y>=0;$y--)
304    {
305     for($x=0;$x<$Width;$x++)
306      {
307       $B=jpexs_freadbyte($f);
308       $G=jpexs_freadbyte($f);
309       $R=jpexs_freadbyte($f);
310       $Ikona[$p]["Data"][$x][$y]["r"]=$R;
311       $Ikona[$p]["Data"][$x][$y]["g"]=$G;
312       $Ikona[$p]["Data"][$x][$y]["b"]=$B;
313      }
314    for($z=0;$z<$Zbytek;$z++)
315     jpexs_freadbyte($f);
316   };
317}
318elseif($biBitCount==32)
319{
320 $Zbytek=$Width%4;
321
322   for($y=$Height-1;$y>=0;$y--)
323    {
324     for($x=0;$x<$Width;$x++)
325      {
326       $B=jpexs_freadbyte($f);
327       $G=jpexs_freadbyte($f);
328       $R=jpexs_freadbyte($f);
329       $Alpha=jpexs_freadbyte($f);
330       $Ikona[$p]["Data"][$x][$y]["r"]=$R;
331       $Ikona[$p]["Data"][$x][$y]["g"]=$G;
332       $Ikona[$p]["Data"][$x][$y]["b"]=$B;
333       $Ikona[$p]["Data"][$x][$y]["alpha"]=$Alpha;
334      }
335    for($z=0;$z<$Zbytek;$z++)
336     jpexs_freadbyte($f);
337   };
338};
339
340
341//Maska
342$Zbytek=(4-ceil(($Width/(8)))%4)%4;
343for($y=$Height-1;$y>=0;$y--)
344    {
345     $jpexs_currentBit=0;
346     for($x=0;$x<$Width;$x++)
347      {
348         $C=jpexs_freadbits($f,1);
349         $Ikona[$p]["Maska"][$x][$y]=$C;
350      };
351    if($jpexs_currentBit!=0) {jpexs_freadbyte($f);};
352    for($g=0;$g<$Zbytek;$g++)
353     jpexs_freadbyte($f);
354     };
355//--------------
356
357fclose($f);
358
359};
360
361function jpexs_GetIconsInfo($filename)
362{
363global $jpexs_currentBit;
364
365$f=fopen($filename,"rb");
366
367$Reserved=jpexs_freadword($f);
368$Type=jpexs_freadword($f);
369$Count=jpexs_freadword($f);
370for($p=0;$p<$Count;$p++)
371 {
372  $Ikona[$p]["Width"]=jpexs_freadbyte($f);
373  $Ikona[$p]["Height"]=jpexs_freadbyte($f);
374  $Ikona[$p]["ColorCount"]=jpexs_freadword($f);
375 if($Ikona[$p]["ColorCount"]==0) $Ikona[$p]["ColorCount"]=256;
376  $Ikona[$p]["Planes"]=jpexs_freadword($f);
377  $Ikona[$p]["BitCount"]=jpexs_freadword($f);
378  $Ikona[$p]["BytesInRes"]=jpexs_freaddword($f);
379  $Ikona[$p]["ImageOffset"]=jpexs_freaddword($f);
380 };
381
382if(!feof($f)):
383  for($p=0;$p<$Count;$p++)
384   {
385    fseek($f,$Ikona[$p]["ImageOffset"]+14);
386    $Ikona[$p]["Info"]["BitsPerPixel"]=jpexs_freadword($f);
387   };
388endif;
389fclose($f);
390return $Ikona;
391};
392
393
394
395
396/**
397 * Reads image from a icon in exe file
398 * @param string $filename Target exefile
399 * @param int $icoIndex Index of the icon in exefile
400 * @param int $icoColorCount Icon color count (For multiple icons ico file) - 2,16,256, ICO_TRUE_COLOR, ICO_XP_COLOR or ICO_MAX_COLOR
401 * @param int $icoSize Icon width (For multiple icons ico file) or ICO_MAX_SIZE
402 * @param int $alphaBgR Background color R value for alpha-channel images (Default is White)
403 * @param int $alphaBgG Background color G value for alpha-channel images (Default is White)
404 * @param int $alphaBgB Background color B value for alpha-channel images (Default is White)
405 * @return resource Image resource or false on error
406 */
407function imageCreateFromExeIco($filename,$icoIndex,$icoColorCount=16,$icoSize=16,$alphaBgR=255,$alphaBgG=255,$alphaBgB=255)
408{
409 $ok=saveExeIcon($filename,"icotemp.dat",$icoIndex);
410 if(!$ok):
411  $im=false;
412 else:
413   $im=imageCreateFromIco("icotemp.dat",$icoColorCount,$icoSize,$alphaBgR,$alphaBgG,$alphaBgB);
414   unlink("icotemp.dat");
415 endif;
416 return $im;
417};
418
419
420/**
421 * Saves icon(s) from the exe file
422 * @global int $jpexs_StartOfRsrc Internal reserved variable
423 * @global int $jpexs_ImageBase Internal reserved variable
424 * @global int $jpexs_ResVirtualAddress Internal reserved variable
425 * @param string $filename Target exefile
426 * @param string $icoFileNameOrPath Filename to save ico or path (Default "") Path if you want more than 1 icon. If "", the filename is "$icoIndex.ico"
427 * @param int|array $iconIndex Index(es) of the icon in exefile  (Default -1) If -1, all icons are saved, Can be an array of indexes.
428 * @return boolean True on successful save
429 */
430function saveExeIcon($filename,$icoFileNameOrPath="",$iconIndex=-1) /*-1 for all,or can be array*/
431{
432  global $jpexs_f,$jpexs_StartOfRsrc,$jpexs_ImageBase,$jpexs_ResVirtualAddress;
433  $jpexs_f=fopen($filename,"r");
434  $MZ=fread($jpexs_f,2);
435  if($MZ!="MZ") NotValidExe();
436  fseek($jpexs_f,60);
437  $OffsetToNewHeader=jpexs_freaddword($jpexs_f);
438  fseek($jpexs_f,$OffsetToNewHeader);
439  $PE=fread($jpexs_f,2);
440  if($PE!="PE") NotValidExe();
441  fread($jpexs_f,4);
442  $NumberOfSections=jpexs_freadword($jpexs_f);
443  fseek($jpexs_f,ftell($jpexs_f)+12);
444  $SizeOfOptionalHeader=jpexs_freadword($jpexs_f);
445  $PosMagic=ftell($jpexs_f)+2;
446  fseek($jpexs_f,$PosMagic+$SizeOfOptionalHeader);
447
448  for($p=0;$p<$NumberOfSections;$p++):
449    $SectionName[$p]=trim(fread($jpexs_f,8));
450    $VirtualSize[$p]=jpexs_freaddword($jpexs_f);
451    $VirtualAddress[$p]=jpexs_freaddword($jpexs_f);
452    $PhysicalSize[$p]=jpexs_freaddword($jpexs_f);
453    $PhysicalOffset[$p]=jpexs_freaddword($jpexs_f);
454    fread($jpexs_f,16);
455    if($SectionName[$p]==".rsrc"):
456      $jpexs_ResVirtualAddress=$VirtualAddress[$p];
457      fseek($jpexs_f,$PhysicalOffset[$p]);
458      $jpexs_StartOfRsrc=$PhysicalOffset[$p];
459      jpexs_readResDirectoryEntry($R,$PhysicalOffset[$p]);
460      $IconCount=null;
461      $Ikona=null;
462      while (list ($key, $val) = each ($R["Subdir"])):
463        if($key==14):
464          $r=0;
465          while (list ($key2, $val2) = each ($R["Subdir"][$key]["Subdir"])):
466             while (list ($key3, $val3) = each ($R["Subdir"][$key]["Subdir"][$key2]["Subdir"])):
467               fseek($jpexs_f,$val3["DataOffset"]);
468               $Reserved=jpexs_freadword($jpexs_f);
469               $Type=jpexs_freadword($jpexs_f);
470               $ic=jpexs_freadword($jpexs_f);
471               $IconCount[]=$ic;
472               for($s=0;$s<$ic;$s++)
473                {
474                 $Ikona[$r][$s]["Width"]=jpexs_freadbyte($jpexs_f);
475                 $Ikona[$r][$s]["Height"]=jpexs_freadbyte($jpexs_f);
476                 $Ikona[$r][$s]["ColorCount"]=jpexs_freadword($jpexs_f);
477                 $Ikona[$r][$s]["Planes"]=jpexs_freadword($jpexs_f);
478                 $Ikona[$r][$s]["BitCount"]=jpexs_freadword($jpexs_f);
479                 $Ikona[$r][$s]["BytesInRes"]=jpexs_freaddword($jpexs_f);
480                 $Ikona[$r][$s]["IconId"]=jpexs_freadword($jpexs_f);
481                };
482               fseek($jpexs_f,$val3["DataOffset"]);
483               $r++;
484             endwhile;
485          endwhile;
486        endif;
487      endwhile;
488
489      reset ($R["Subdir"]);
490
491      while (list ($key, $val) = each ($R["Subdir"])):
492        if($key==3):
493          while (list ($key2, $val2) = each ($R["Subdir"][$key]["Subdir"])):
494          for($r=0;$r<count($Ikona);$r++):
495           for($s=0;$s<count($Ikona[$r]);$s++):
496             while (list ($key3, $val3) = each ($R["Subdir"][$key]["Subdir"][$Ikona[$r][$s]["IconId"]]["Subdir"])):
497               if(($iconIndex==$r)or($iconIndex==-1)or((is_array($iconIndex))and(in_array($r,$iconIndex)))):
498                 fseek($jpexs_f,$val3["DataOffset"]);
499                 $Ikona[$r][$s]["Data"]=fread($jpexs_f,$val3["DataSize"]);
500                 $Ikona[$r][$s]["DataSize"]=$val3["DataSize"];
501               endif;
502             endwhile;
503           endfor;
504           endfor;
505          endwhile;
506        endif;
507      endwhile;
508      $ok=false;
509      for($r=0;$r<count($Ikona);$r++):
510        if(($iconIndex==$r)or($iconIndex==-1)or((is_array($iconIndex))and(in_array($r,$iconIndex)))):
511          $savefile=$icoFileNameOrPath;
512          if($icoFileNameOrPath=="")
513           {
514             $savefile="$r.ico";
515           }
516           else
517           {
518            if(($iconIndex==-1)or(is_array($iconIndex)))
519              $savefile=$icoFileNameOrPath."$r.ico";
520           };
521          $f2=fopen($savefile,"w");
522          fwrite($f2,jpexs_inttoword(0));
523          fwrite($f2,jpexs_inttoword(1));
524          fwrite($f2,jpexs_inttoword(count($Ikona[$r])));
525          $Offset=6+16*count($Ikona[$r]);
526          for($s=0;$s<count($Ikona[$r]);$s++):
527            fwrite($f2,jpexs_inttobyte($Ikona[$r][$s]["Width"]));
528            fwrite($f2,jpexs_inttobyte($Ikona[$r][$s]["Height"]));
529            fwrite($f2,jpexs_inttoword($Ikona[$r][$s]["ColorCount"]));
530            fwrite($f2,jpexs_inttoword($Ikona[$r][$s]["Planes"]));
531            fwrite($f2,jpexs_inttoword($Ikona[$r][$s]["BitCount"]));
532            fwrite($f2,jpexs_inttodword($Ikona[$r][$s]["BytesInRes"]));
533            fwrite($f2,jpexs_inttodword($Offset));
534            $Offset+=$Ikona[$r][$s]["DataSize"];
535          endfor;
536          for($s=0;$s<count($Ikona[$r]);$s++):
537            fwrite($f2,$Ikona[$r][$s]["Data"]);
538          endfor;
539          fclose($f2);
540          $ok=true;
541        endif;
542      endfor;
543      return $ok;
544    endif;
545  endfor;
546
547  fclose($jpexs_f);
548};
549
550/**
551 * Internal function for reading exe icons
552 */
553function jpexs_readResDirectoryEntry(&$parentRes,$offset)
554{
555global $jpexs_f,$jpexs_StartOfRsrc,$jpexs_ImageBase,$jpexs_ResVirtualAddress;
556$lastPos=ftell($jpexs_f);
557$Res=null;
558fseek($jpexs_f,$offset);
559//IMAGE_RESOURCE_DIRECTORY
560      $Characteristics=jpexs_freaddword($jpexs_f);
561      $TimeDateStamp=jpexs_freaddword($jpexs_f);
562      $MajorVersion=jpexs_freadword($jpexs_f);
563      $MinorVersion=jpexs_freadword($jpexs_f);
564      $NumberOfNamedEntries=jpexs_freadword($jpexs_f);
565      $NumberOfIdEntries=jpexs_freadword($jpexs_f);
566      for($q=0;$q<$NumberOfNamedEntries+$NumberOfIdEntries;$q++):
567        //IMAGE_RESOURCE_DIRECTORY_ENTRY
568        $ResName=jpexs_freaddword($jpexs_f);
569        $lastPos2=ftell($jpexs_f);
570        if($ResName>=0x80000000):
571          //String Name
572          $ResNameOffset=$ResName-0x80000000;
573          fseek($jpexs_f,$jpexs_StartOfRsrc+$ResNameOffset);
574          $StringLength=jpexs_freadword($jpexs_f);
575          $Identificator=(fread($jpexs_f,$StringLength*2));
576          fseek($jpexs_f,$lastPos2);
577        else:
578          //Integer Id
579          $Identificator=$ResName;
580        endif;
581
582        $ResOffsetToData=jpexs_freaddword($jpexs_f);
583        if($ResOffsetToData>=0x80000000):
584          $SubResOffset=$ResOffsetToData-0x80000000;
585          jpexs_readResDirectoryEntry($Res["$Identificator"],$jpexs_StartOfRsrc+$SubResOffset);
586        else:
587          $RawDataOffset=$ResOffsetToData;
588          $lastPos2=ftell($jpexs_f);
589          fseek($jpexs_f,$jpexs_StartOfRsrc+$RawDataOffset);
590          //IMAGE_RESOURCE_DATA_ENTRY
591          $OffsetToData=jpexs_freaddword($jpexs_f);
592          $Res["$Identificator"]["DataOffset"]=$jpexs_StartOfRsrc-$jpexs_ResVirtualAddress+$OffsetToData;
593          $Res["$Identificator"]["DataSize"]=jpexs_freaddword($jpexs_f);
594          $CodePage=jpexs_freaddword($jpexs_f);
595          $Reserved=jpexs_freaddword($jpexs_f);
596          fseek($jpexs_f,$lastPos2);
597        endif;
598      endfor;
599fseek($jpexs_f,$lastPos);
600$parentRes["Subdir"]=$Res;
601};
602
603/**
604 * Creates ico file from image resource(s)
605 * @param resource|array $images Target Image resource (Can be array of image resources)
606 * @param string $filename Target ico file to save icon to, If ommited or "", image is written to snadard output - use header("Content-type: image/x-icon"); */
607function imageIco($images,$filename="")
608{
609
610if(is_array($images))
611{
612$ImageCount=count($images);
613$Image=$images;
614}
615else
616{
617$Image[0]=$images;
618$ImageCount=1;
619};
620
621
622$WriteToFile=false;
623
624if($filename!="")
625{
626$WriteToFile=true;
627};
628
629
630$ret="";
631
632$ret.=jpexs_inttoword(0); //PASSWORD
633$ret.=jpexs_inttoword(1); //SOURCE
634$ret.=jpexs_inttoword($ImageCount); //ICONCOUNT
635
636
637for($q=0;$q<$ImageCount;$q++)
638{
639$img=$Image[$q];
640
641$Width=imagesx($img);
642$Height=imagesy($img);
643
644$ColorCount=imagecolorstotal($img);
645
646$Transparent=imagecolortransparent($img);
647$IsTransparent=$Transparent!=-1;
648
649
650if($IsTransparent) $ColorCount--;
651
652if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
653if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
654if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
655if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
656
657
658
659
660
661//ICONINFO:
662$ret.=jpexs_inttobyte($Width);//
663$ret.=jpexs_inttobyte($Height);//
664$ret.=jpexs_inttobyte($ColorCount);//
665$ret.=jpexs_inttobyte(0);//RESERVED
666
667$Planes=0;
668if($BitCount>=8) $Planes=1;
669
670$ret.=jpexs_inttoword($f,$Planes);//PLANES
671if($BitCount>=8) $WBitCount=$BitCount;
672if($BitCount==4) $WBitCount=0;
673if($BitCount==1) $WBitCount=0;
674$ret.=jpexs_inttoword($WBitCount);//BITS
675
676$Zbytek=(4-($Width/(8/$BitCount))%4)%4;
677$ZbytekMask=(4-($Width/8)%4)%4;
678
679$PalSize=0;
680
681$Size=40+($Width/(8/$BitCount)+$Zbytek)*$Height+(($Width/8+$ZbytekMask) * $Height);
682if($BitCount<24)
683 $Size+=pow(2,$BitCount)*4;
684$IconId=1;
685$ret.=jpexs_inttodword($Size); //SIZE
686$OffSet=6+16*$ImageCount+$FullSize;
687$ret.=jpexs_inttodword(6+16*$ImageCount+$FullSize);//OFFSET
688$FullSize+=$Size;
689//-------------
690
691};
692
693
694for($q=0;$q<$ImageCount;$q++)
695{
696$img=$Image[$q];
697$Width=imagesx($img);
698$Height=imagesy($img);
699$ColorCount=imagecolorstotal($img);
700
701$Transparent=imagecolortransparent($img);
702$IsTransparent=$Transparent!=-1;
703
704if($IsTransparent) $ColorCount--;
705if($ColorCount==0) {$ColorCount=0; $BitCount=24;};
706if(($ColorCount>0)and($ColorCount<=2)) {$ColorCount=2; $BitCount=1;};
707if(($ColorCount>2)and($ColorCount<=16)) { $ColorCount=16; $BitCount=4;};
708if(($ColorCount>16)and($ColorCount<=256)) { $ColorCount=0; $BitCount=8;};
709
710
711
712//ICONS
713$ret.=jpexs_inttodword(40);//HEADSIZE
714$ret.=jpexs_inttodword($Width);//
715$ret.=jpexs_inttodword(2*$Height);//
716$ret.=jpexs_inttoword(1); //PLANES
717$ret.=jpexs_inttoword($BitCount);   //
718$ret.=jpexs_inttodword(0);//Compress method
719
720
721$ZbytekMask=($Width/8)%4;
722
723$Zbytek=($Width/(8/$BitCount))%4;
724$Size=($Width/(8/$BitCount)+$Zbytek)*$Height+(($Width/8+$ZbytekMask) * $Height);
725
726$ret.=jpexs_inttodword($Size);//SIZE
727
728$ret.=jpexs_inttodword(0);//HPIXEL_M
729$ret.=jpexs_inttodword(0);//V_PIXEL_M
730$ret.=jpexs_inttodword($ColorCount); //UCOLORS
731$ret.=jpexs_inttodword(0); //DCOLORS
732//---------------
733
734
735$CC=$ColorCount;
736if($CC==0) $CC=256;
737
738if($BitCount<24)
739{
740 $ColorTotal=imagecolorstotal($img);
741 if($IsTransparent) $ColorTotal--;
742
743 for($p=0;$p<$ColorTotal;$p++)
744  {
745   $color=imagecolorsforindex($img,$p);
746   $ret.=jpexs_inttobyte($color["blue"]);
747   $ret.=jpexs_inttobyte($color["green"]);
748   $ret.=jpexs_inttobyte($color["red"]);
749   $ret.=jpexs_inttobyte(0); //RESERVED
750  };
751
752 $CT=$ColorTotal;
753 for($p=$ColorTotal;$p<$CC;$p++)
754  {
755   $ret.=jpexs_inttobyte(0);
756   $ret.=jpexs_inttobyte(0);
757   $ret.=jpexs_inttobyte(0);
758   $ret.=jpexs_inttobyte(0); //RESERVED
759  };
760};
761
762
763
764
765
766
767if($BitCount<=8)
768{
769
770 for($y=$Height-1;$y>=0;$y--)
771 {
772  $bWrite="";
773  for($x=0;$x<$Width;$x++)
774   {
775   $color=imagecolorat($img,$x,$y);
776   if($color==$Transparent)
777    $color=imagecolorexact($img,0,0,0);
778   if($color==-1) $color=0;
779   if($color>pow(2,$BitCount)-1) $color=0;
780
781   $bWrite.=jpexs_decbinx($color,$BitCount);
782   if(strlen($bWrite)==8)
783    {
784     $ret.=jpexs_inttobyte(bindec($bWrite));
785     $bWrite="";
786    };
787   };
788
789  if((strlen($bWrite)<8)and(strlen($bWrite)!=0))
790    {
791     $sl=strlen($bWrite);
792     for($t=0;$t<8-$sl;$t++)
793      $sl.="0";
794     $ret.=jpexs_inttobyte(bindec($bWrite));
795    };
796  for($z=0;$z<$Zbytek;$z++)
797   $ret.=jpexs_inttobyte(0);
798 };
799};
800
801
802
803if($BitCount>=24)
804{
805 for($y=$Height-1;$y>=0;$y--)
806 {
807  for($x=0;$x<$Width;$x++)
808   {
809   $color=imagecolorsforindex($img,imagecolorat($img,$x,$y));
810   $ret.=jpexs_inttobyte($color["blue"]);
811   $ret.=jpexs_inttobyte($color["green"]);
812   $ret.=jpexs_inttobyte($color["red"]);
813   if($BitCount==32)
814    $ret.=jpexs_inttobyte(0);//Alpha for ICO_XP_COLORS
815   };
816  for($z=0;$z<$Zbytek;$z++)
817   $ret.=jpexs_inttobyte(0);
818 };
819};
820
821
822//MASK
823
824 for($y=$Height-1;$y>=0;$y--)
825 {
826  $byteCount=0;
827  $bOut="";
828  for($x=0;$x<$Width;$x++)
829   {
830    if(($Transparent!=-1)and(imagecolorat($img,$x,$y)==$Transparent))
831     {
832      $bOut.="1";
833     }
834     else
835     {
836      $bOut.="0";
837     };
838   };
839  for($p=0;$p<strlen($bOut);$p+=8)
840  {
841   $byte=bindec(substr($bOut,$p,8));
842   $byteCount++;
843   $ret.=jpexs_inttobyte($byte);
844  };
845 $Zbytek=$byteCount%4;
846  for($z=0;$z<$Zbytek;$z++)
847   {
848   $ret.=jpexs_inttobyte(0xff);
849   };
850 };
851
852//------------------
853
854};//q
855
856
857
858
859
860if($WriteToFile)
861{
862 $f=fopen($filename,"w");
863 fwrite($f,$ret);
864 fclose($f);
865}
866else
867{
868 echo $ret;
869};
870
871};
872
873
874
875
876/*
877* Internal functions:
878*-------------------------
879* jpexs_inttobyte($n) - returns chr(n)
880* jpexs_inttodword($n) - returns dword (n)
881* jpexs_inttoword($n) - returns word(n)
882* jpexs_freadbyte($file) - reads 1 byte from $file
883* jpexs_freadword($file) - reads 2 bytes (1 word) from $file
884* jpexs_freaddword($file) - reads 4 bytes (1 dword) from $file
885* jpexs_freadlngint($file) - same as freaddword($file)
886* jpexs_decbin8($d) - returns binary string of d zero filled to 8
887* jpexs_RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte
888* jpexs_freadbits($file,$count) - reads next $count bits from $file
889*/
890
891
892function jpexs_decbin8($d)
893{
894return jpexs_decbinx($d,8);
895};
896
897function jpexs_decbinx($d,$n)
898{
899$bin=decbin($d);
900$sbin=strlen($bin);
901for($j=0;$j<$n-$sbin;$j++)
902 $bin="0$bin";
903return $bin;
904};
905
906function jpexs_retBits($byte,$start,$len)
907{
908$bin=jpexs_decbin8($byte);
909$r=bindec(substr($bin,$start,$len));
910return $r;
911
912};
913
914
915
916$jpexs_currentBit=0;
917function jpexs_freadbits($f,$count)
918{
919 global $jpexs_currentBit,$jpexs_SMode;
920 $Byte=jpexs_freadbyte($f);
921 $LastCBit=$jpexs_currentBit;
922 $jpexs_currentBit+=$count;
923 if($jpexs_currentBit==8)
924  {
925   $jpexs_currentBit=0;
926  }
927 else
928  {
929   fseek($f,ftell($f)-1);
930  };
931 return jpexs_retBits($Byte,$LastCBit,$count);
932};
933
934
935function jpexs_freadbyte($f)
936{
937 return ord(fread($f,1));
938};
939
940function jpexs_freadword($f)
941{
942 $b1=jpexs_freadbyte($f);
943 $b2=jpexs_freadbyte($f);
944 return $b2*256+$b1;
945};
946
947
948function jpexs_freadlngint($f)
949{
950return jpexs_freaddword($f);
951};
952
953function jpexs_freaddword($f)
954{
955 $b1=jpexs_freadword($f);
956 $b2=jpexs_freadword($f);
957 return $b2*65536+$b1;
958};
959
960function jpexs_inttobyte($n)
961{
962return chr($n);
963};
964
965function jpexs_inttodword($n)
966{
967return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255);
968};
969
970function jpexs_inttoword($n)
971 {
972 return chr($n & 255).chr(($n >> 8) & 255);
973 };
974
975?>