WordPress.org

Make WordPress Core

Ticket #16434: trac-16434-04.patch

File trac-16434-04.patch, 50.0 KB (added by TomAuger, 2 years ago)

Included ico2_3.php, "remove" functionality, and refactoring of get_favicon_thumbnail_img() to get_favicon_img()

  • wp-admin/favicon-upload.php

     
     1<?php 
     2/** 
     3 * Handles the uploading, cropping and scaling of favicons. 
     4 *  
     5 * @uses ico2_3.php JPEXS class for reading / writing .ICO files 
     6 *  
     7 * @package WordPress 
     8 * @subpackage Administration 
     9 * @since 3.4.1 
     10 */ 
     11 
     12// Bootstrap admin and all its goodies 
     13require_once( 'admin.php' ); 
     14 
     15// Bring in the JPEXS .ICO conversion library 
     16require_once( ABSPATH . 'wp-admin/includes/ico2_3.php' ); 
     17 
     18 
     19define( 'FAVICON_SIZE', 32 ); // Width (and height) of the favicon (in pixels) 
     20 
     21/*      Upload is a 2-step process:      
     22 *      1. Process the uploaded file and show the crop UI 
     23 *      2. Manipulate the pixel data, save to PNG and ICO and write to options. 
     24 */ 
     25 
     26if ( isset( $_POST['CROP_AND_SAVE'] ) ) { 
     27        if ( isset( $_POST['attachment_id'] ) && is_numeric( $_POST['attachment_id'] ) ){ 
     28                $image_basename = process_crop_thumbnail( $_POST['attachment_id'] ); 
     29 
     30                if ( is_wp_error( $image_basename ) ) { 
     31                        include_once('./admin-header.php'); 
     32                        echo '<div class="wrap">'; 
     33                                echo '<h2>' . __( 'Image upload error' ) . '</h2>'; 
     34                                echo '<p>' . $image_basename->get_error_message() . '</p>'; 
     35                                echo '<p><a href="' . admin_url( 'options-general.php' ) . '">&laquo;' . __( 'Back to Settings &gt; General' ) . '</a></p>'; 
     36                        echo '</div><!-- .wrap -->'; 
     37                        include_once('./admin-footer.php'); 
     38                } else { 
     39                        foreach ( array( $image_basename . '.png', $image_basename . '.ico' ) as $image_filename ) 
     40                                save_thumbnail_attachment( $image_filename, $attachment_id ); 
     41 
     42                        // And save the basename out to options. 
     43                        update_option( 'sitefavicon', basename( $image_basename ) ); 
     44                         
     45                        /** @TODO need to find a way to notify the user that the process has completed successfully - admin_notices? */ 
     46                        wp_redirect( admin_url( 'options-general.php' ) ); 
     47                }  
     48        } else { 
     49                return new WP_Error( 'attachment_id_missing', 'Form submission error.' ); 
     50        } 
     51} elseif ( isset( $_REQUEST['REMOVE_FAVICON'] ) ) { 
     52        remove_favicon(); 
     53} else { 
     54        /** @TODO make sure that we trap for someone just pressing "Upload image" but with no image attached */ 
     55        // Enqueue the JS for the cropper... 
     56        add_action( 'admin_enqueue_scripts', 'enqueue_cropper' ); 
     57        // ...and our own script for populating the crop form 
     58        add_action( 'admin_footer', 'cropping_js', 10,  1); 
     59         
     60        // Process the upload and create the attachment file in the media center 
     61        $image_results = process_thumbnail_upload(); 
     62         
     63        include_once('./admin-header.php'); 
     64         
     65        // hack because image replication isn't fast enough. See https://wpcom.automattic.com/ticket/1294 
     66        sleep( 2 ); 
     67 
     68        echo '<div class="wrap">'; 
     69         
     70        if ( is_wp_error( $image_results ) )  { 
     71                echo '<h2>' . __( 'Image upload error' ) . '</h2>'; 
     72                echo '<p>' . $image_results->get_error_message() . '</p>'; 
     73                echo '<p><a href="' . admin_url( 'options-general.php' ) . '">&laquo;' . __( 'Back to Settings &gt; General' ) . '</a></p>'; 
     74        } else { 
     75                // Image upload successful. 
     76                // Now we can hook in our javascript and provide the width/height of our image as the default crop size 
     77                $crop_size = min( $image_results['width'], $image_results['height'] ); 
     78                echo '<script type="text/javascript">var jcrop_starting_size = ' . $crop_size . '; // Initialize jcrop crop area starting size</script>'; 
     79         
     80                echo '<h2>' . __( 'Crop uploaded image' ) . '</h2>'; 
     81                echo '<p>' . __( 'Choose the part of the image you want to use for your favicon.' ) . '</p>'; 
     82                 
     83                echo '<form id="favicon-crop-form" method="post" action="' . $_SERVER['REQUEST_URI'] . '">'; // Point the form action back to this script 
     84                 
     85                        echo <<<CROP_FORM 
     86                        <input type="hidden" name="x1" id="x1" /> 
     87                        <input type="hidden" name="y1" id="y1" /> 
     88                        <input type="hidden" name="x2" id="x2" /> 
     89                        <input type="hidden" name="y2" id="y2" /> 
     90                        <input type="hidden" name="width" id="width" /> 
     91                        <input type="hidden" name="height" id="height" /> 
     92                        <input type="hidden" name="attachment_id" id="attachment_id" value="{$image_results['attachment_id']}" /> 
     93                        <input type="hidden" name="scaling_factor" id="scaling_factor" value="{$image_results['scaling_factor']}" /> 
     94CROP_FORM; 
     95                 
     96                        echo '<img src="' . $image_results['src'] . '" id="upload" width="' . $image_results['width'] . '" height="' . $image_results['height'] . '" />'; 
     97                 
     98                        echo '<p class="submit"><input type="submit" name="CROP_AND_SAVE" value="' . __( 'Crop image' ) . ' &raquo;" /></p>'; 
     99                echo '</form>'; 
     100        } 
     101         
     102        echo '</div><!-- .wrap -->'; 
     103         
     104        include_once('./admin-footer.php'); 
     105} 
     106 
     107 
     108/** 
     109 * Process the image file upload and return a WP_Error or details about the attachment image file. 
     110 *  
     111 * @return mixed WP_Error | $image_results array  
     112 */ 
     113function process_thumbnail_upload(){ 
     114        $file = wp_handle_upload( $_FILES['avatarfile'], array( 'action' => 'wp_upload_favicon') ); 
     115        if ( isset($file['error']) ) die( $file['error'] ); 
     116         
     117        $url = $file['url']; 
     118        $file = $file['file']; 
     119        $filename = basename($file); 
     120         
     121        // Construct the object array 
     122        $object = array( 
     123                'post_title' => $filename, 
     124                'post_content' => $url, 
     125                'post_mime_type' => 'import', 
     126                'guid' => $url 
     127        ); 
     128 
     129        // Save the data.  Also makes replication work 
     130        $id = wp_insert_attachment($object, $file); 
     131 
     132        // Retrieve the image dimensions 
     133        list( $orig_width, $orig_height, $type, $attr ) = getimagesize( $file ); 
     134         
     135        // Do we need to scale down the image so we can display it nicely in the interactive Crop tool? 
     136        if ( $orig_width > 600 || $orig_height > 600 ) { 
     137                $image = wp_create_thumbnail( $file, 600 ); 
     138                list( $width, $height, $type, $attr ) = getimagesize( $image ); 
     139                 
     140                 // Update the attachment record to reflect the newly-scaled thumbnail image 
     141                $thumb = basename( $image ); 
     142                $metadata = array( 'thumb' => $thumb ); 
     143                wp_update_attachment_metadata( $id, $metadata ); 
     144 
     145                $url = str_replace( basename( $url ), $thumb, $url ); 
     146 
     147                $scaling = $orig_width / $width; 
     148        } else { 
     149                // No scaling required; just copy original values. 
     150                $width = $orig_width; 
     151                $height = $orig_height; 
     152                $scaling = 1; 
     153        } 
     154 
     155        // Check image file format 
     156        $image_type = exif_imagetype( get_attached_file( $id ) ); 
     157        if (! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP ) ) ) 
     158                $error = new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg) or BMP (.bmp) image files for favicons. ' ) ); 
     159         
     160        // return WP_Error or the $image_results array 
     161        if ( $error ){ 
     162                return $error; 
     163        } else { 
     164                return array(  
     165                        'attachment_id' => $id, 
     166                        'src' => $url, 
     167                        'width' => $width, 
     168                        'height' => $height, 
     169                        'scaling_factor' => $scaling 
     170                ); 
     171        } 
     172} 
     173 
     174/** 
     175 * Create PNG and BMP image resources based on the form submission of the cropped thumbnail. 
     176 *  
     177 * @param int $attachment_id The ID of the original attachment's post record. 
     178 * @return mixed WP_Error | Favicon file base name (ie: fully qualified file name without any TLA file extension) 
     179 */ 
     180function process_crop_thumbnail( $attachment_id ){ 
     181        $src_file = get_attached_file( $attachment_id ); 
     182 
     183        // Highly unlikely, but let's check 
     184        if (! file_exists( $src_file ) ) 
     185                return new WP_Error( 'file_missing', __( 'Attachment image file missing (possible save error: check space on web server).' ) ); 
     186 
     187        // Make sure we're still within accepted image types 
     188        $image_type = exif_imagetype( $src_file ); 
     189        if (! $image_type || ! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP ) ) ) 
     190                return new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg) or BMP (.bmp) image files for favicons. ' ) ); 
     191 
     192        // Parse image file bytes 
     193        $src_image = wp_load_image( $src_file ); 
     194        if ( !is_resource($src_image) ) 
     195                return new WP_Error( 'is_not_resource', __( 'Error loading image. You got me: I\'m stumped.' ) );  
     196 
     197        // We crop from the original, not the medium sized, display-only thumbnail 
     198        $src_x = $_POST['x1'] * $_POST['scaling_factor']; 
     199        $src_y = $_POST['y1'] * $_POST['scaling_factor']; 
     200        $src_width = $_POST['width'] * $_POST['scaling_factor']; 
     201        $src_height = $_POST['height'] * $_POST['scaling_factor']; 
     202 
     203        $dst_width = $dst_height = FAVICON_SIZE; 
     204        // Avoid upscaling 
     205        if ( $src_width < $dst_width || $src_height < $dst_height ) { 
     206                $dst_width = $src_width; 
     207                $dst_height = $src_height; 
     208        } 
     209 
     210        $dst_image = wp_imagecreatetruecolor( $dst_width, $dst_height ); 
     211        if ( function_exists( 'imageantialias' ) ) imageantialias( $dst_image, true ); 
     212        imagealphablending( $dst_image, false ); 
     213        imagesavealpha( $dst_image, true ); 
     214        imagecopyresampled( $dst_image, $src_image, 0, 0, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height ); 
     215        imagedestroy( $src_image ); 
     216 
     217 
     218        // Save the image in PNG and ICO formats 
     219        $file_info = pathinfo( $src_file ); 
     220        $src_basename = basename( $src_file, '.' . $file_info['extension'] ); 
     221        $dst_filename = str_replace( $src_basename, $src_basename . '_' . FAVICON_SIZE . 'x' . FAVICON_SIZE, $src_file ); 
     222        // Strip the TLA from the filename 
     223        $dst_filename = preg_replace( '/\\.[^\\.]+$/', '', $dst_filename ); 
     224 
     225        $png_filename = $dst_filename . '.png'; 
     226        if (! imagepng( $dst_image, $png_filename, 0 ) ) 
     227                return new WP_Error( 'png_write_error', 'Error writing PNG favicon file.' ); 
     228         
     229        $ico_filename = $dst_filename . '.ico'; 
     230        imageIco( $dst_image, $ico_filename ); 
     231        /** @TODO refactor the ico2_3.php library to add error checking and possibly encapsulate the class */ 
     232        //if (! imageIco( $dst_image, $ico_filename ) ) 
     233                //return new WP_Error( 'ico_write_error', 'Error writing ICO favicon file.' ); 
     234 
     235        imagedestroy( $dst_image ); 
     236 
     237        return $dst_filename; 
     238} 
     239 
     240/** 
     241 * Creates an attachment post record for a newly created thumbnail 
     242 *  
     243 * @param string $file_name Fully qualified file name for the image asset file. 
     244 * @param int $parent_attachment_id The ID of the original thumbnail's attachment post record 
     245 *  
     246 * @return int The ID of the newly-created thumbnail attachment post record 
     247 */ 
     248function save_thumbnail_attachment( $file_name, $parent_attachment_id ){ 
     249        $file_info = pathinfo( $file_name ); // So we can get the TLA later on 
     250         
     251        $file_name = apply_filters( 'wp_create_file_in_uploads', $file_name, $parent_attachment_id ); // For replication 
     252 
     253        $parent = get_post( $parent_attachment_id ); 
     254        $parent_url = $parent->guid; 
     255         
     256        // Update the attachment 
     257        $mimes = get_allowed_mime_types(); 
     258        $attachment_id = wp_insert_attachment( array( 
     259                'ID' => $attachment_id, 
     260                'post_title' => basename( $file_name ), 
     261                'post_content' => $url, 
     262                'post_mime_type' => $mimes[ $file_info['extension'] ], 
     263                'guid' => $url, 
     264                'context' => 'favicon' 
     265        ), $file_name ); 
     266        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file_name ) ); 
     267         
     268        return $attachment_id; 
     269} 
     270 
     271/** 
     272 * Currently, doesn't actually "remove" the favicon images. It only deletes the option 
     273 * that tells us there's a favicon, so the code isn't generated (or the default is used) 
     274 */ 
     275function remove_favicon(){ 
     276        update_option( 'sitefavicon', false ); 
     277                         
     278        /** @TODO need to find a way to notify the user that the process has completed successfully - admin_notices? */ 
     279        wp_redirect( admin_url( 'options-general.php' ) ); 
     280} 
     281 
     282 
     283/** 
     284 * Called in admin_enqueue_scripts to add the cropper.js script and styles 
     285 */ 
     286function enqueue_cropper(){ 
     287        wp_enqueue_script( 'jcrop', 'jquery' ); 
     288        wp_enqueue_style('jcrop'); // We can enqueue styles within the admin_enqueue_script action hook {@link http://wpdevel.wordpress.com/2011/12/12/use-wp_enqueue_scripts-not-wp_print_styles-to-enqueue-scripts-and-styles-for-the-frontend/} 
     289} 
     290 
     291function cropping_js(){ 
     292        // Purely for coding convenience and legibility 
     293        $favicon_size = FAVICON_SIZE; 
     294         
     295        echo <<<CROP_JS 
     296        <!-- Favicon cropping --> 
     297        <script type="text/javascript"> 
     298                // Update the crop form 
     299                function onEndCrop( coords ) { 
     300                        jQuery( '#x1' ).val(coords.x); 
     301                        jQuery( '#y1' ).val(coords.y); 
     302                        jQuery( '#x2' ).val(coords.x2); 
     303                        jQuery( '#y2' ).val(coords.y2); 
     304                        jQuery( '#width' ).val(coords.w); 
     305                        jQuery( '#height' ).val(coords.h); 
     306                } 
     307 
     308                // with a supplied ratio 
     309                jQuery(function($) { 
     310                        if (! jcrop_starting_size) jcrop_starting_size = {$favicon_size}; // jcrop_starting_size should be set in the body once the image has been processed 
     311 
     312                        // Set up default values on the crop form 
     313                        jQuery( '#x1' ).val(0); 
     314                        jQuery( '#y1' ).val(0); 
     315                        jQuery( '#x2' ).val(jcrop_starting_size); 
     316                        jQuery( '#y2' ).val(jcrop_starting_size); 
     317                        jQuery( '#width' ).val(jcrop_starting_size); 
     318                        jQuery( '#height' ).val(jcrop_starting_size); 
     319 
     320                        // Initialize Jcrop 
     321                        $('#upload').Jcrop({ 
     322                                aspectRatio: 1, 
     323                                setSelect: [0, 0, jcrop_starting_size, jcrop_starting_size], 
     324                                onSelect: onEndCrop 
     325                        }); 
     326                }); 
     327        </script> 
     328CROP_JS; 
     329 
     330} 
     331 No newline at end of file 
  • wp-admin/includes/ico2_3.php

     
     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?> 
     976 No newline at end of file 
  • wp-admin/js/wp-favicon.dev.js

     
     1(function($){ 
     2    $('#faviconfile').change(function(){ 
     3        // check the file extention 
     4        if (! $.inArray( $(this).val().split('.').pop().toLowerCase() , /* valid file extentions */ ['gif','png','jpg','jpeg'] ) )  
     5            $('#favicon-invalid-filetype').show(); 
     6        else 
     7        { 
     8            $('#faviconupload').submit(); 
     9        } 
     10    }); 
     11 
     12})(jQuery); 
  • wp-admin/js/wp-favicon.js

     
     1(function($){ 
     2    $('#faviconfile').change(function(){ 
     3        // check the file extention 
     4        if (! $.inArray( $(this).val().split('.').pop().toLowerCase() , /* valid file extentions */ ['gif','png','jpg','jpeg'] ) )  
     5            $('#favicon-invalid-filetype').show(); 
     6        else 
     7        { 
     8            $('#faviconupload').submit(); 
     9        } 
     10    }); 
     11 
     12})(jQuery); 
  • wp-admin/options-general.php

     
    8181        '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>' 
    8282); 
    8383 
     84wp_enqueue_script('wp-favicon'); 
     85 
    8486include('./admin-header.php'); 
    8587?> 
    8688 
     
    8890<?php screen_icon(); ?> 
    8991<h2><?php echo esc_html( $title ); ?></h2> 
    9092 
     93<form action="<?php echo admin_url('favicon-upload.php')?>" method="post" enctype="multipart/form-data" id="faviconupload"> 
     94        <input type="hidden" name="action" value="wp_upload_favicon" /> 
     95 
     96        <table class="form-table"> 
     97                <tr valign="top"> 
     98                        <th scope="row"><label for="sitefavicon"><?php _e('Favicon') ?></label></th> 
     99                        <td> 
     100                                <?php 
     101                                        // display the icon and the remove link if appropriate 
     102                                        if ( has_custom_favicon() ){ 
     103                                                if ( $thumbnail = get_favicon_img() ) echo $thumbnail; 
     104                                                echo "\t" . '<input type="submit" name="REMOVE_FAVICON" value="Remove Favicon" id="remove-favicon-button" />'; 
     105                                                echo ' <span class="description no-js">' . __( 'The image at right is used as your site\'s favicon. To change it, first remove this one.' ) . '</span>'; 
     106                                        } else { 
     107                                ?> 
     108                                        <input class="button" name="avatarfile" type="file" id="faviconfile" size="20" /> 
     109                                        <p class="submit no-js hide-if-js"><input type="submit" name="Submit" value="Upload Image &raquo;" id="faviconsubmit" /></p> 
     110                                        <span class="description no-js"><?php _e('Click to upload your own custom icon ("favicon") for your blog. You\'ll be able to crop and scale it once it\'s uploaded.') ?></span> 
     111                                <?php } ?> 
     112                        </td> 
     113                </tr> 
     114        </table> 
     115</form> 
     116 
    91117<form method="post" action="options.php"> 
    92118<?php settings_fields('general'); ?> 
    93119 
  • wp-includes/functions.php

     
    18451845                'png' => 'image/png', 
    18461846                'bmp' => 'image/bmp', 
    18471847                'tif|tiff' => 'image/tiff', 
    1848                 'ico' => 'image/x-icon', 
     1848                'ico' => 'image/vnd.microsoft.icon', 
    18491849                'asf|asx|wax|wmv|wmx' => 'video/asf', 
    18501850                'avi' => 'video/avi', 
    18511851                'divx' => 'video/divx', 
  • wp-includes/general-template.php

     
    15871587} 
    15881588 
    15891589/** 
     1590 * Convenience function that echoes the HTML for the site's favicon icon. 
     1591 * By default, automatically included in the header via the 'wp_head' action, which can be removed by themes if a custom favicon is desired. 
     1592 *  
     1593 * @uses generate_site_favicon_html() to do the actual heavy lifting 
     1594 */ 
     1595function site_favicon(){ 
     1596        echo generate_site_favicon_html(); 
     1597} 
     1598add_action( 'wp_head', 'site_favicon' ); 
     1599add_action( 'admin_head', 'site_favicon' ); 
     1600 
     1601/** 
     1602 * Return the HTML for the site's favicon icon, if such has been defined. 
     1603 *  
     1604 * @uses get_site_favicon_uri(); 
     1605 *  
     1606 * Includes the conditional tag wrapper for an IE (.ico) version.  
     1607 */ 
     1608function generate_site_favicon_html() { 
     1609        $ie_favicon_uri = get_site_favicon_uri( 'ico' ); 
     1610        $favicon_uri = get_site_favicon_uri(); 
     1611 
     1612        $content = ""; 
     1613        if (! is_wp_error( $ie_favicon_uri ) && ! is_wp_error( $favicon_uri ) ){ 
     1614 
     1615                $content .= <<<FAVICON_HTML 
     1616<!--Favicon (via 'wp_head' action) --> 
     1617<!--[if IE]> 
     1618<link rel="shortcut icon" href="{$ie_favicon_uri}" /> 
     1619<![endif]--> 
     1620<!--[if !IE]>--> 
     1621<link href="{$favicon_uri}" rel="icon" type="image/png" /> 
     1622<!--<![endif]--> 
     1623FAVICON_HTML; 
     1624    } 
     1625        return $content; 
     1626} 
     1627 
     1628/** 
     1629 * Get the attachment post object associated with the current site favicon, based on the 'sitefavicon' option 
     1630 *  
     1631 * @param string $format Default 'png'. Format of the file we're looking for 
     1632 * @return object If found, returns the post object; if not, a WP_Error object 
     1633 */ 
     1634function get_site_favicon_attachment( $format = 'png' ){ 
     1635        $favicon_basename = get_option ( 'sitefavicon' );  
     1636         
     1637        if ( ! empty( $favicon_basename ) ) { 
     1638                $favicon_fullname = $favicon_basename . '-' . $format; 
     1639                 
     1640                $posts = get_posts( array( 'name' => $favicon_fullname, 'post_type' => 'attachment' ) ); 
     1641                if ( $posts[0] ){ 
     1642                        return $posts[0]; 
     1643                } else { 
     1644                        return new WP_Error( 'attachment_missing', __( "No attachment for '$favicon_fullname' was found." ) ); 
     1645                } 
     1646        } else { 
     1647                return new WP_Error( 'not_defined', __( "No favicon file provided." ) ); 
     1648        } 
     1649} 
     1650 
     1651/** 
     1652 * Returns the URI for the site's favicon based on the option set in  Admin > Settings > General. 
     1653 *  
     1654 * @param string $format png|ico default 'png'. Use 'ico' for serving up an IE-compatible ICO file 
     1655 * @return string fully qualified URI  
     1656 */ 
     1657function get_site_favicon_uri( $format = 'png' ){ 
     1658        /** @TODO provide error checking for validity of $format and $size */ 
     1659        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1660         
     1661        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1662        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1663                return wp_get_attachment_url( $favicon_attachment->ID ); 
     1664        } 
     1665         
     1666        // We get here because of an error condition 
     1667        /** @TODO default to the theme's favicon **/ 
     1668        // ATM do nothing (so URI is blank, rather than a WP_Error) 
     1669} 
     1670 
     1671/** 
     1672 * Gets the path to the favicon file, or returns a WP_Error 
     1673 * @param string $format Default 'png' 
     1674 * @return mixed File string or WP_Error object  
     1675 */ 
     1676function get_site_favicon_file( $format = 'png' ){ 
     1677        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1678         
     1679        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1680        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1681                return get_attached_file( $favicon_attachment->ID ); 
     1682        } else { 
     1683                return $favicon_attachment; // returns the WP_Error object 
     1684        } 
     1685} 
     1686 
     1687/** 
     1688 * Returns true or false depending on whether a custom favicon has been defined in Admin 
     1689 * @return boolean  
     1690 */ 
     1691function has_custom_favicon(){ 
     1692        $favicon_basename = get_option ( 'sitefavicon' );  
     1693        /** @TODO more robust checking: don't just check that the option has been set: check that the file exists */ 
     1694        return ( ! empty( $favicon_basename ) ); 
     1695} 
     1696 
     1697/** 
     1698 * Returns an HTML <img> tag populated with the site favicon, in the format specified (usually PNG) 
     1699 * @param string $format Default 'png'. Valid values are 'png', 'bmp' (note 'ico' is NOT valid) 
     1700 * @return mixed Returns HTML <img> tag or WP_Error if invalid format given. Returns nothing if the file is missing.  
     1701 */ 
     1702function get_favicon_img( $format = 'png' ){ 
     1703        if (in_array( strtolower( $format ), array( 'png', 'bmp' ) ) ){ 
     1704                // Does the file actually exist? 
     1705                $file = get_site_favicon_file( $format ); 
     1706                if (! is_wp_error( $file ) && file_exists( $file ) ){ 
     1707                        $src = get_site_favicon_uri( $format ); 
     1708                        if (!is_wp_error( $src ) ){ 
     1709                                return '<img src="' . $src . '" alt="' . _x( 'Site favicon thumbnail', 'Thumbnail image accessibility text' ) .'" />'; 
     1710                        } 
     1711                } 
     1712        } else { 
     1713                return new WP_Error( 'invalid_file_format', __( 'Invalid file format. Valid formats are "png", "bmp".' ) ); 
     1714        } 
     1715} 
     1716 
     1717/** 
    15901718 * Display the links to the general feeds. 
    15911719 * 
    15921720 * @since 2.8.0 
  • wp-includes/script-loader.php

     
    8888 
    8989        $scripts->add( 'wp-fullscreen', "/wp-admin/js/wp-fullscreen$suffix.js", array('jquery'), false, 1 ); 
    9090 
     91        $scripts->add( 'wp-favicon', "/wp-admin/js/wp-favicon$suffix.js", array('jquery'), false, 1 ); 
     92 
    9193        $scripts->add( 'prototype', '/wp-includes/js/prototype.js', array(), '1.6.1'); 
    9294 
    9395        $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array('jquery'), false, 1 );