WordPress.org

Make WordPress Core

Ticket #16434: trac-16434-05.patch

File trac-16434-05.patch, 56.0 KB (added by tomauger, 6 years ago)

Re-integrated ico library, large scale refactoring, same great taste.

  • wp-admin/css/wp-admin.dev.css

     
    48524852        vertical-align: middle; 
    48534853} 
    48544854 
     4855.options-general-php img.favicon { 
     4856        vertical-align:middle; 
     4857         
     4858        -moz-box-shadow:    1px 1px 3px 0px #aaa; 
     4859        -webkit-box-shadow: 1px 1px 3px 0px #aaa; 
     4860        box-shadow:         1px 1px 3px 0px #aaa; 
     4861} 
    48554862 
     4863#remove-favicon-button { 
     4864        margin-left:5px; 
     4865} 
     4866 
     4867/* Favicon upload error messages */ 
     4868#favicon-invalid-filetype-error { 
     4869        display:none; 
     4870        color:red; 
     4871        font-style: italic; 
     4872} 
     4873 
     4874 
    48564875/*------------------------------------------------------------------------------ 
    48574876  21.0 - Admin Footer 
    48584877------------------------------------------------------------------------------*/ 
  • wp-admin/favicon-upload.php

     
     1<?php 
     2/** 
     3 * Handles the uploading, cropping and scaling of favicons. 
     4 *  
     5 * @package WordPress 
     6 * @subpackage Administration 
     7 * @since 3.4.1 
     8 */ 
     9 
     10// Bootstrap admin and all its goodies 
     11require_once( 'admin.php' ); 
     12 
     13define( 'DEFAULT_FAVICON_SIZE', 32 ); // Width (and height) of the favicon (in pixels). Use 'favicon_size' filter to over-ride this value 
     14 
     15if (! current_user_can('manage_options') ) 
     16    wp_die( __( 'Cheatin&#8217; eh?' ) ); 
     17 
     18check_admin_referer( 'favicon_upload-options' ); 
     19 
     20$title = __( 'Crop Favicon' ); 
     21$parent_file = 'options-general.php'; 
     22 
     23// Main workflow 
     24// Favicon removal 
     25if ( isset( $_REQUEST['REMOVE_FAVICON'] ) ) { 
     26        remove_favicon(); 
     27        wp_redirect( admin_url( $parent_file ) ); 
     28        exit; 
     29} 
     30 
     31// Process crop operation 
     32if ( isset( $_POST['CROP_AND_SAVE'] ) ) { 
     33        if ( isset( $_POST['attachment_id'] ) && is_numeric( $_POST['attachment_id'] ) ){ 
     34                $favicon_image_res = process_crop_thumbnail( $_POST['attachment_id'] ); 
     35                if (! is_wp_error( $favicon_image_res ) ){ 
     36                        if (! is_wp_error( generate_favicon_formats( $favicon_image_res, $_POST['attachment_id'] ) ) ){ 
     37                                // And save the basename out to options. 
     38                                update_option( 'sitefavicon', basename( generate_favicon_basename( $_POST['attachment_id'] ) ) ); 
     39                                // We're done. 
     40                                wp_redirect( admin_url( $parent_file ) ); 
     41                                exit; 
     42                        } else { 
     43                                _show_favicon_error_page( __( 'Error generating favicon files.' ) ); 
     44                        } 
     45                } else { 
     46                        _show_favicon_error_page( $image_basename->get_error_message() ); 
     47                } 
     48        } else { 
     49                _show_favicon_error_page(); 
     50        } 
     51}  
     52// Process image upload 
     53else { 
     54        $upload_results = process_thumbnail_upload(); 
     55         
     56        if (! is_wp_error( $upload_results ) ){ 
     57                // Does it need to be scaled / cropped? 
     58                if ( $upload_results['width'] > 32 || $upload_results['height'] > 32 ){ 
     59                        display_crop_form( $upload_results ); 
     60                } else { 
     61                        // Short-circuit the crop operation and just save the raw unscaled image 
     62                        if (! is_wp_error( generate_favicon_formats( load_favicon_image( $upload_results['file'] ), $upload_results['attachment_id'] ) ) ){ 
     63                                // And save the basename out to options. 
     64                                update_option( 'sitefavicon', basename( generate_favicon_basename( $upload_results['attachment_id'] ) ) ); 
     65                                wp_redirect( admin_url( $parent_file ) ); 
     66                                exit; 
     67                        } else { 
     68                                _show_favicon_error_page( __( 'Error generating favicon files.' ) ); 
     69                        } 
     70                } 
     71        } else { 
     72                // Some kind of upload error 
     73                _show_favicon_error_page( $upload_results->get_error_message() ); 
     74        } 
     75} 
     76 
     77 
     78/** 
     79 * Generic utility function to display a general error message within the options page structure. 
     80 *  
     81 * @param string $message optional. A specific message describing the error condition for the end user. 
     82 * @param string $title optional. The heading for this error. 
     83 */ 
     84function _show_favicon_error_page( $message = '', $title = '' ){ 
     85        if ( empty( $message ) ) $message = __( 'Image upload failed. Please try again.' ); 
     86        if ( empty( $title ) ) $title = __( 'Favicon upload error' ); 
     87         
     88        include_once('./admin-header.php'); 
     89                echo '<div class="wrap favicon-error">'; 
     90                        echo "<h2>{$title}</h2>"; 
     91                        echo "<p>{$message}</p>"; 
     92                        echo '<p><a href="' . admin_url( $parent_file ) . '">&laquo;' . __( 'Back to Settings &gt; General' ) . '</a></p>'; 
     93                echo '</div><!-- .wrap -->'; 
     94        include_once('./admin-footer.php'); 
     95} 
     96 
     97/** 
     98 * Process the image file upload and return a WP_Error or details about the attachment image file. 
     99 * Image results will return an array consisting of: 
     100 *              'attachment_id' => ID of the attachment DB record 
     101 *              'src' => URL of the img src 
     102 *              'width' => width ( = height ) 
     103 *              'type' => the image type 
     104 *              'attr' => other attributes 
     105 *              'file' => the uploaded file path 
     106 *  
     107 * @uses apply_filters( 'wp_favicon_max_crop_size' ) to set the maximum display size of the image in the crop form 
     108 *  
     109 * @return mixed WP_Error | $image_info array  
     110 */ 
     111function process_thumbnail_upload(){ 
     112        $file = wp_handle_upload( $_FILES['avatarfile'], array( 'action' => 'update') ); 
     113        if ( isset($file['error']) ) die( $file['error'] ); 
     114         
     115        $url = $file['url']; 
     116        $file = $file['file']; 
     117         
     118        // Check image file format 
     119        $image_type = exif_imagetype( $file ); 
     120        if (! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_ICO ) ) ) 
     121                return new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg), GIF (.gif) or ICO (.ico) image files for favicons.' ) ); 
     122         
     123        $filename = basename( $file ); 
     124         
     125        // Construct the object array 
     126        $object = array( 
     127                'post_title' => $filename, 
     128                'post_content' => $url, 
     129                'post_mime_type' => 'import', 
     130                'guid' => $url 
     131        ); 
     132 
     133        // Save the data.  Also makes replication work 
     134        $id = wp_insert_attachment( $object, $file ); 
     135 
     136        // Retrieve the image dimensions 
     137        list( $width, $height, $type, $attr ) = getimagesize( $file ); 
     138 
     139        return array(  
     140                'attachment_id' => $id, 
     141                'src' => $url, 
     142                'width' => $width, 
     143                'height' => $height, 
     144                'type' => $type, 
     145                'attr' => $attr, 
     146                'file' => $file 
     147        ); 
     148} 
     149 
     150 
     151function load_favicon_image( $file ){ 
     152        $file_info = pathinfo( $file ); 
     153        if ( strtolower( $file_info['extension'] ) == 'ico' ){ 
     154                return imageCreateFromIco( $file, ICO_MAX_COLOR, ICO_MAX_SIZE ); 
     155        } else { 
     156                return wp_load_image( $file ); 
     157        } 
     158} 
     159 
     160 
     161/** 
     162 * Displays the form for cropping the thumbnail. Leverages the jcrop javascript library. 
     163 *  
     164 * @uses wp_create_thumbnail() 
     165 *  
     166 * @param array $image_info Array of properties as output by {@link process_thumbnail_upload()} 
     167 */ 
     168function display_crop_form( $image_info ){ 
     169        // Do we need to scale down the image so we can display it nicely in the interactive Crop tool? 
     170        $max_crop_display_size = apply_filters( 'wp_favicon_max_crop_size', 600 ); 
     171        if ( $image_info['width'] > $max_crop_display_size || $image_info['height'] > $max_crop_display_size ) { 
     172                // Create and save a new thumbnail file at the new size 
     173                $image = wp_create_thumbnail( $image_info['file'], $max_crop_display_size ); 
     174                list( $width, $height, $type, $attr ) = getimagesize( $image ); 
     175                 
     176                 // Update the attachment record to reflect the newly-scaled thumbnail image 
     177                $thumb = basename( $image ); 
     178                $metadata = array( 'thumb' => $thumb ); 
     179                wp_update_attachment_metadata( $id, $metadata ); 
     180 
     181                $url = str_replace( basename( $url ), $thumb, $url ); 
     182 
     183                $scaling = $image_info['width'] / $width; 
     184        } else { 
     185                // No scaling required; just copy original values. 
     186                $width = $image_info['width']; 
     187                $height = $image_info['height']; 
     188                $scaling = 1; 
     189        } 
     190         
     191        /** 
     192         * Display the crop form, leveraging the jcrop library. 
     193         */ 
     194         
     195        // Enqueue the JS for the cropper... 
     196        add_action( 'admin_enqueue_scripts', 'enqueue_cropper' ); 
     197        // ...and our own script for populating the crop form 
     198        add_action( 'admin_footer', 'cropping_js', 10,  1); 
     199         
     200        include_once('./admin-header.php'); 
     201 
     202        echo '<div class="wrap">'; 
     203                // Now we can hook in our javascript and provide the width/height of our image as the default crop size 
     204                $crop_size = min( $width, $height ); //because it's gotta be square... 
     205                echo '<script type="text/javascript">var jcrop_starting_size = ' . $crop_size . '; // Initialize jcrop crop area starting size</script>'; 
     206         
     207                echo '<h2>' . __( 'Crop uploaded image' ) . '</h2>'; 
     208                echo '<p>' . __( 'Choose the part of the image you want to use for your favicon.' ) . '</p>'; 
     209                 
     210                echo '<form id="favicon-crop-form" method="post" action="' . $_SERVER['REQUEST_URI'] . '">'; // Point the form action back to this script 
     211        settings_fields( 'favicon_upload' );     
     212                ?> 
     213                        <input type="hidden" name="x1" id="x1" /> 
     214                        <input type="hidden" name="y1" id="y1" /> 
     215                        <input type="hidden" name="x2" id="x2" /> 
     216                        <input type="hidden" name="y2" id="y2" /> 
     217                        <input type="hidden" name="width" id="width" /> 
     218                        <input type="hidden" name="height" id="height" /> 
     219                        <input type="hidden" name="attachment_id" id="attachment_id" value="<?php echo $image_info['attachment_id']?>" /> 
     220                        <input type="hidden" name="scaling_factor" id="scaling_factor" value="<?php echo $scaling ?>" /> 
     221                <?php 
     222                 
     223                        echo '<img src="' . $image_info['src'] . '" id="upload" width="' . $width . '" height="' . $height . '" />';             
     224                        echo '<p class="submit"><input type="submit" name="CROP_AND_SAVE" value="' . __( 'Crop image' ) . ' &raquo;" /></p>'; 
     225                echo '</form>'; 
     226         
     227        echo '</div><!-- .wrap -->'; 
     228         
     229        include_once('./admin-footer.php'); 
     230} 
     231 
     232/** 
     233 * Create PNG and BMP image resources based on the form submission of the cropped thumbnail. 
     234 *  
     235 * @uses apply_filters( 'favicon_size' ) to set the favicon size in pixels. 
     236 *  
     237 * @param int $attachment_id The ID of the original attachment's post record. 
     238 * @return mixed WP_Error | scaled and cropped image resource 
     239 */ 
     240function process_crop_thumbnail( $attachment_id ){ 
     241        $src_file = get_attached_file( $attachment_id ); 
     242 
     243        // Highly unlikely, but let's check 
     244        if (! file_exists( $src_file ) ) 
     245                return new WP_Error( 'file_missing', __( 'Attachment image file missing (possible save error: check space on web server).' ) ); 
     246 
     247        // Make sure we're still within accepted image types 
     248        $image_type = exif_imagetype( $src_file ); 
     249        if (! $image_type || ! in_array( $image_type, array( IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP ) ) ) 
     250                return new WP_Error( 'bad_file_format', __( 'Please only use PNG (.png), JPEG (.jpg) or BMP (.bmp) image files for favicons. ' ) ); 
     251 
     252        // Parse image file bytes 
     253        $src_image = wp_load_image( $src_file ); 
     254        if ( !is_resource($src_image) ) 
     255                return new WP_Error( 'is_not_resource', __( 'Error loading image. You got me: I\'m stumped.' ) );  
     256 
     257        // We crop from the original, not the medium sized, display-only thumbnail 
     258        $src_x = $_POST['x1'] * $_POST['scaling_factor']; 
     259        $src_y = $_POST['y1'] * $_POST['scaling_factor']; 
     260        $src_width = $_POST['width'] * $_POST['scaling_factor']; 
     261        $src_height = $_POST['height'] * $_POST['scaling_factor']; 
     262 
     263        $dst_width = $dst_height = apply_filters( 'favicon_size', DEFAULT_FAVICON_SIZE ); 
     264        // Avoid upscaling 
     265        if ( $src_width < $dst_width || $src_height < $dst_height ) { 
     266                $dst_width = $src_width; 
     267                $dst_height = $src_height; 
     268        } 
     269 
     270        $dst_image = wp_imagecreatetruecolor( $dst_width, $dst_height ); 
     271        if ( function_exists( 'imageantialias' ) ) imageantialias( $dst_image, true ); 
     272        imagealphablending( $dst_image, false ); 
     273        imagesavealpha( $dst_image, true ); 
     274        imagecopyresampled( $dst_image, $src_image, 0, 0, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height ); 
     275        imagedestroy( $src_image ); 
     276 
     277        return $dst_image; 
     278} 
     279 
     280/** 
     281 * Generate the base filename. The .png and .ico versions will be this base name + the appropriate 3 letter extension (tla) 
     282 * This will be in the form of "filename-32x32" where '32' in this case is replaced by the actual icon dimensions 
     283 *  
     284 * @param int $attachment_id The uploaded (and possibly cropped) attachment ID 
     285 * @returns string the base name of the favicon thumbnail, stripped of any file extension 
     286 */ 
     287function generate_favicon_basename( $attachment_id ) { 
     288        /** @TODO rename and move this to image.php and refactor image_resize() to use this function so we're not duplicating efforts */ 
     289        $src_file = get_attached_file( $attachment_id ); 
     290         
     291        list ( $width, $height ) = getimagesize( $src_file ); 
     292 
     293        $file_info = pathinfo( $src_file ); 
     294        $src_basename = basename( $src_file, '.' . $file_info['extension'] ); 
     295        $dst_filename = str_replace( $src_basename, $src_basename . '-' . $width . 'x' . $height, $src_file ); 
     296        // Strip the TLA from the filename (shouldn't be there anymore, but you can't be too careful...) 
     297        $dst_filename = preg_replace( '/\\.[^\\.]+$/', '', $dst_filename ); 
     298         
     299        return $dst_filename; 
     300} 
     301 
     302/** 
     303 * Creates and saves out the PNG and the ICO version of the thumbnail, when provided with the source resource. 
     304 * Also creates an attachment record for each. 
     305 *  
     306 * @uses save_thumbnail_attachment(); 
     307 *  
     308 * @param type $source_image_resource 
     309 * @param type $file_basename 
     310 * @return \WP_Error  
     311 */ 
     312function generate_favicon_formats( $source_image_resource, $attachment_id ) { 
     313        if (! is_resource( $source_image_resource ) ) die( 'No resource provided. Cannot generate favicon files.' ); 
     314 
     315        $file_basename = generate_favicon_basename( $attachment_id ); 
     316         
     317        // Save out the PNG 
     318        $png_filename = $file_basename . '.png'; 
     319        if (! imagepng( $source_image_resource, $png_filename, 0 ) ) 
     320                return new WP_Error( 'png_write_error', 'Error writing PNG favicon file.' ); 
     321        save_thumbnail_attachment( $png_filename, $attachment_id ); 
     322         
     323        //Save out the ICO 
     324        $ico_filename = $file_basename . '.ico'; 
     325        imageIco( $source_image_resource, $ico_filename ); 
     326        /** @TODO refactor the ico2_3.php library to add error checking and possibly encapsulate the class */ 
     327        //if (! imageIco( $dst_image, $ico_filename ) ) 
     328                //return new WP_Error( 'ico_write_error', 'Error writing ICO favicon file.' ); 
     329                save_thumbnail_attachment( $ico_filename, $attachment_id ); 
     330 
     331        imagedestroy( $dst_image ); 
     332} 
     333 
     334/** 
     335 * Creates an attachment post record for a newly created thumbnail 
     336 *  
     337 * @param string $file_name Fully qualified file name for the image asset file. 
     338 * @param int $parent_attachment_id The ID of the original thumbnail's attachment post record 
     339 *  
     340 * @return int The ID of the newly-created thumbnail attachment post record 
     341 */ 
     342function save_thumbnail_attachment( $file_name, $parent_attachment_id ){ 
     343        $file_info = pathinfo( $file_name ); // So we can get the TLA later on 
     344         
     345        $file_name = apply_filters( 'wp_create_file_in_uploads', $file_name, $parent_attachment_id ); // For replication 
     346 
     347        $parent = get_post( $parent_attachment_id ); 
     348        $parent_url = $parent->guid; 
     349         
     350        // Update the attachment 
     351        $mimes = get_allowed_mime_types(); 
     352        $attachment_id = wp_insert_attachment( array( 
     353                'post_title' => basename( $file_name ), 
     354                'post_mime_type' => $mimes[ $file_info['extension'] ], 
     355                'context' => 'favicon' 
     356        ), $file_name ); 
     357        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file_name ) ); 
     358         
     359        return $attachment_id; 
     360} 
     361 
     362/** 
     363 * Currently, doesn't actually "remove" the favicon images. It only deletes the option 
     364 * that tells us there's a favicon, so the code isn't generated (or the default is used) 
     365 */ 
     366function remove_favicon(){ 
     367        update_option( 'sitefavicon', false ); 
     368                         
     369        /** @TODO need to find a way to notify the user that the process has completed successfully - admin_notices? */ 
     370} 
     371 
     372 
     373/** 
     374 * Called in admin_enqueue_scripts to add the cropper.js script and styles 
     375 */ 
     376function enqueue_cropper(){ 
     377        wp_enqueue_script( 'jcrop', 'jquery' ); 
     378        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/} 
     379} 
     380 
     381/** 
     382 * Output the JavaScript that drives the jcrop cropping process. 
     383 *  
     384 * @uses apply_filters( 'favicon_size' ) to set the favicon size in pixels 
     385 */ 
     386function cropping_js(){ 
     387        // Purely for coding convenience and legibility 
     388        $favicon_size = apply_filters( 'favicon_size', DEFAULT_FAVICON_SIZE ); 
     389         
     390        echo <<<CROP_JS 
     391        <!-- Favicon cropping --> 
     392        <script type="text/javascript"> 
     393                // Update the crop form 
     394                function onEndCrop( coords ) { 
     395                        jQuery( '#x1' ).val(coords.x); 
     396                        jQuery( '#y1' ).val(coords.y); 
     397                        jQuery( '#x2' ).val(coords.x2); 
     398                        jQuery( '#y2' ).val(coords.y2); 
     399                        jQuery( '#width' ).val(coords.w); 
     400                        jQuery( '#height' ).val(coords.h); 
     401                } 
     402 
     403                // with a supplied ratio 
     404                jQuery(function($) { 
     405                        if (! jcrop_starting_size) jcrop_starting_size = {$favicon_size}; // jcrop_starting_size should be set in the body once the image has been processed 
     406 
     407                        // Set up default values on the crop form 
     408                        jQuery( '#x1' ).val(0); 
     409                        jQuery( '#y1' ).val(0); 
     410                        jQuery( '#x2' ).val(jcrop_starting_size); 
     411                        jQuery( '#y2' ).val(jcrop_starting_size); 
     412                        jQuery( '#width' ).val(jcrop_starting_size); 
     413                        jQuery( '#height' ).val(jcrop_starting_size); 
     414 
     415                        // Initialize Jcrop 
     416                        $('#upload').Jcrop({ 
     417                                aspectRatio: 1, 
     418                                setSelect: [0, 0, jcrop_starting_size, jcrop_starting_size], 
     419                                onSelect: onEndCrop 
     420                        }); 
     421                }); 
     422        </script> 
     423CROP_JS; 
     424 
     425} 
     426 
     427 
     428 
     429 
     430 
     431 
     432/** 
     433 * @package com.jpexs.image.ico 
     434 * 
     435 * JPEXS ICO Image functions 
     436 * @version 2.3 
     437 * @author JPEXS 
     438 * @copyright (c) JPEXS 2004-2012 
     439 * 
     440 * Webpage: http://www.jpexs.com 
     441 * Email: jpexs@jpexs.com 
     442 * 
     443 * If you like my script, you can donate... visit my webpages or email me for more info. 
     444 * 
     445 *        Version changes: 
     446 *          2012-02-25 v2.3 - License changed to GNU/GPL v2 or v3 
     447 *          2012-02-18 v2.2 - License changed to GNU/GPL v3 
     448 *          2009-02-23 v2.1 - redesigned sourcecode, phpdoc included, all internal functions and global variables have prefix "jpexs_" 
     449 *                     v2.0 - For icons with Alpha channel now you can set background color 
     450 *                          - ImageCreateFromExeIco added 
     451 *                          - Fixed ICO_MAX_SIZE and ICO_MAX_COLOR values 
     452 * 
     453 * TODO list: 
     454 *      - better error handling 
     455 *      - better internal function handling 
     456 *      - class encapsulation 
     457 *  
     458 * License: 
     459 *  This program is free software: you can redistribute it and/or modify 
     460 *  it under the terms of the GNU General Public License as published by 
     461 *  the Free Software Foundation, either version 2 or version 3 of the License, or 
     462 *  (at your option) any later version. 
     463 *  
     464 *  This program is distributed in the hope that it will be useful, 
     465 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
     466 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     467 *  GNU General Public License for more details. 
     468 *  
     469 *  You should have received a copy of the GNU General Public License 
     470 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
     471 */ 
     472 
     473/** TrueColor images constant  */ 
     474define( "ICO_TRUE_COLOR", 0x1000000 ); 
     475/** XPColor images constant (Alpha channel) */ 
     476define( "ICO_XP_COLOR", 4294967296 ); 
     477/** Image with maximum colors */ 
     478define( "ICO_MAX_COLOR", -2 ); 
     479/** Image with maximal size */ 
     480define( "ICO_MAX_SIZE", -2 ); 
     481 
     482 
     483/** TrueColor images constant 
     484 * @deprecated Deprecated since version 2.1, please use ICO_ constants 
     485 */ 
     486define( "TRUE_COLOR", 0x1000000 ); 
     487/** XPColor images constant (Alpha channel) 
     488 * @deprecated Deprecated since version 2.1, please use ICO_ constants 
     489 */ 
     490define( "XP_COLOR", 4294967296 ); 
     491/** Image with maximum colors 
     492 * @deprecated Deprecated since version 2.1, please use ICO_ constants 
     493 */ 
     494define( "MAX_COLOR", -2 ); 
     495/** Image with maximal size 
     496 * @deprecated Deprecated since version 2.1, please use ICO_ constants 
     497 */ 
     498define( "MAX_SIZE", -2 ); 
     499 
     500 
     501/** 
     502 * Reads image from a ICO file 
     503 * 
     504 * @param string $filename Target ico file to load 
     505 * @param int $icoColorCount Icon color count (For multiple icons ico file) - 2,16,256, ICO_TRUE_COLOR, ICO_XP_COLOR or ICO_MAX_COLOR 
     506 * @param int $icoSize Icon width (For multiple icons ico file) or ICO_MAX_SIZE 
     507 * @param int $alphaBgR Background color R value for alpha-channel images (Default is White) 
     508 * @param int $alphaBgG Background color G value for alpha-channel images (Default is White) 
     509 * @param int $alphaBgB Background color B value for alpha-channel images (Default is White) 
     510 * @return resource Image resource 
     511 */ 
     512function imageCreateFromIco( $filename, $icoColorCount = 16, $icoSize = 16, $alphaBgR = 255, $alphaBgG = 255, $alphaBgB = 255 ) { 
     513        $Ikona = jpexs_GetIconsInfo( $filename ); 
     514         
     515        $IconID = -1; 
     516         
     517        $ColMax = -1; 
     518        $SizeMax = -1; 
     519         
     520        for ( $p = 0; $p < count( $Ikona ); $p++ ) { 
     521                $Ikona[ $p ][ "NumberOfColors" ] = pow( 2, $Ikona[ $p ][ "Info" ][ "BitsPerPixel" ] ); 
     522        } 
     523         
     524         
     525        for ( $p = 0; $p < count( $Ikona ); $p++ ) { 
     526                if ( ( $ColMax == -1 ) or ( $Ikona[ $p ][ "NumberOfColors" ] >= $Ikona[ $ColMax ][ "NumberOfColors" ] ) ) 
     527                        if ( ( $icoSize == $Ikona[ $p ][ "Width" ] ) or ( $icoSize == ICO_MAX_SIZE ) ) { 
     528                                $ColMax = $p; 
     529                        } 
     530                 
     531                if ( ( $SizeMax == -1 ) or ( $Ikona[ $p ][ "Width" ] >= $Ikona[ $SizeMax ][ "Width" ] ) ) 
     532                        if ( ( $icoColorCount == $Ikona[ $p ][ "NumberOfColors" ] ) or ( $icoColorCount == ICO_MAX_COLOR ) ) { 
     533                                $SizeMax = $p; 
     534                        } 
     535                 
     536                 
     537                if ( $Ikona[ $p ][ "NumberOfColors" ] == $icoColorCount ) 
     538                        if ( $Ikona[ $p ][ "Width" ] == $icoSize ) { 
     539                                $IconID = $p; 
     540                        } 
     541        } 
     542         
     543        if ( $icoColorCount == ICO_MAX_COLOR ) 
     544                $IconID = $ColMax; 
     545        if ( $icoSize == ICO_MAX_SIZE ) 
     546                $IconID = $SizeMax; 
     547         
     548        $ColName = $icoColorCount; 
     549         
     550        if ( $icoSize == ICO_MAX_SIZE ) 
     551                $icoSize = "Max"; 
     552        if ( $ColName == ICO_TRUE_COLOR ) 
     553                $ColName = "True"; 
     554        if ( $ColName == ICO_XP_COLOR ) 
     555                $ColName = "XP"; 
     556        if ( $ColName == ICO_MAX_COLOR ) 
     557                $ColName = "Max"; 
     558        if ( $IconID == -1 ) 
     559                die( "Icon with $ColName colors and $icoSize x $icoSize size doesn't exist in this file!" ); 
     560         
     561         
     562        jpexs_readIcon( $filename, $IconID, $Ikona ); 
     563         
     564        $biBitCount = $Ikona[ $IconID ][ "Info" ][ "BitsPerPixel" ]; 
     565         
     566         
     567        if ( $Ikona[ $IconID ][ "Info" ][ "BitsPerPixel" ] == 0 ) { 
     568                $Ikona[ $IconID ][ "Info" ][ "BitsPerPixel" ] = 24; 
     569        } 
     570         
     571        $biBitCount = $Ikona[ $IconID ][ "Info" ][ "BitsPerPixel" ]; 
     572        if ( $biBitCount == 0 ) 
     573                $biBitCount = 1; 
     574         
     575         
     576        $Ikona[ $IconID ][ "BitCount" ] = $Ikona[ $IconID ][ "Info" ][ "BitsPerPixel" ]; 
     577         
     578         
     579         
     580        if ( $Ikona[ $IconID ][ "BitCount" ] >= 24 ) { 
     581                $img = imagecreatetruecolor( $Ikona[ $IconID ][ "Width" ], $Ikona[ $IconID ][ "Height" ] ); 
     582                if ( $Ikona[ $IconID ][ "BitCount" ] == 32 ): 
     583                        $backcolor = imagecolorallocate( $img, $alphaBgR, $alphaBgG, $alphaBgB ); 
     584                        imagefilledrectangle( $img, 0, 0, $Ikona[ $IconID ][ "Width" ] - 1, $Ikona[ $IconID ][ "Height" ] - 1, $backcolor ); 
     585                endif; 
     586                for ( $y = 0; $y < $Ikona[ $IconID ][ "Height" ]; $y++ ) 
     587                        for ( $x = 0; $x < $Ikona[ $IconID ][ "Width" ]; $x++ ) { 
     588                                $R = $Ikona[ $IconID ][ "Data" ][ $x ][ $y ][ "r" ]; 
     589                                $G = $Ikona[ $IconID ][ "Data" ][ $x ][ $y ][ "g" ]; 
     590                                $B = $Ikona[ $IconID ][ "Data" ][ $x ][ $y ][ "b" ]; 
     591                                if ( $Ikona[ $IconID ][ "BitCount" ] == 32 ) { 
     592                                        $Alpha = 127 - round( $Ikona[ $IconID ][ "Data" ][ $x ][ $y ][ "alpha" ] * 127 / 255 ); 
     593                                        if ( $Ikona[ $IconID ][ "Maska" ][ $x ][ $y ] == 1 ) 
     594                                                $Alpha = 127; 
     595                                        $color = imagecolorexactalpha( $img, $R, $G, $B, $Alpha ); 
     596                                        if ( $color == -1 ) 
     597                                                $color = imagecolorallocatealpha( $img, $R, $G, $B, $Alpha ); 
     598                                } else { 
     599                                        $color = imagecolorexact( $img, $R, $G, $B ); 
     600                                        if ( $color == -1 ) 
     601                                                $color = imagecolorallocate( $img, $R, $G, $B ); 
     602                                } 
     603                                 
     604                                imagesetpixel( $img, $x, $y, $color ); 
     605                                 
     606                        } 
     607                 
     608        } else { 
     609                $img = imagecreate( $Ikona[ $IconID ][ "Width" ], $Ikona[ $IconID ][ "Height" ] ); 
     610                for ( $p = 0; $p < count( $Ikona[ $IconID ][ "Paleta" ] ); $p++ ) 
     611                        $Paleta[ $p ] = imagecolorallocate( $img, $Ikona[ $IconID ][ "Paleta" ][ $p ][ "r" ], $Ikona[ $IconID ][ "Paleta" ][ $p ][ "g" ], $Ikona[ $IconID ][ "Paleta" ][ $p ][ "b" ] ); 
     612                 
     613                for ( $y = 0; $y < $Ikona[ $IconID ][ "Height" ]; $y++ ) 
     614                        for ( $x = 0; $x < $Ikona[ $IconID ][ "Width" ]; $x++ ) { 
     615                                imagesetpixel( $img, $x, $y, $Paleta[ $Ikona[ $IconID ][ "Data" ][ $x ][ $y ] ] ); 
     616                        } 
     617        } 
     618        $IsTransparent = false; 
     619        for ( $y = 0; $y < $Ikona[ $IconID ][ "Height" ]; $y++ ) 
     620                for ( $x = 0; $x < $Ikona[ $IconID ][ "Width" ]; $x++ ) 
     621                        if ( $Ikona[ $IconID ][ "Maska" ][ $x ][ $y ] == 1 ) { 
     622                                $IsTransparent = true; 
     623                                break; 
     624                        } 
     625        if ( $Ikona[ $IconID ][ "BitCount" ] == 32 ) { 
     626                imagealphablending( $img, false ); 
     627                if ( function_exists( "imagesavealpha" ) ) 
     628                        imagesavealpha( $img, true ); 
     629        } 
     630         
     631        if ( $IsTransparent ) { 
     632                if ( ( $Ikona[ $IconID ][ "BitCount" ] >= 24 ) or ( imagecolorstotal( $img ) >= 256 ) ) { 
     633                        $img2 = imagecreatetruecolor( imagesx( $img ), imagesy( $img ) ); 
     634                        imagecopy( $img2, $img, 0, 0, 0, 0, imagesx( $img ), imagesy( $img ) ); 
     635                        imagedestroy( $img ); 
     636                        $img = $img2; 
     637                        imagetruecolortopalette( $img, true, 255 ); 
     638                         
     639                } 
     640                $Pruhledna = imagecolorallocate( $img, 0, 0, 0 ); 
     641                for ( $y = 0; $y < $Ikona[ $IconID ][ "Height" ]; $y++ ) 
     642                        for ( $x = 0; $x < $Ikona[ $IconID ][ "Width" ]; $x++ ) 
     643                                if ( $Ikona[ $IconID ][ "Maska" ][ $x ][ $y ] == 1 ) { 
     644                                        imagesetpixel( $img, $x, $y, $Pruhledna ); 
     645                                } 
     646                imagecolortransparent( $img, $Pruhledna ); 
     647        } 
     648         
     649        return $img; 
     650         
     651         
     652} 
     653 
     654 
     655 
     656 
     657function jpexs_readIcon( $filename, $id, &$Ikona ) { 
     658        global $jpexs_currentBit; 
     659         
     660        $f = fopen( $filename, "rb" ); 
     661         
     662        fseek( $f, 6 + $id * 16 ); 
     663        $Width = jpexs_freadbyte( $f ); 
     664        $Height = jpexs_freadbyte( $f ); 
     665        fseek( $f, 6 + $id * 16 + 12 ); 
     666        $OffSet = jpexs_freaddword( $f ); 
     667        fseek( $f, $OffSet ); 
     668         
     669        $p = $id; 
     670         
     671        $Ikona[ $p ][ "Info" ][ "HeaderSize" ] = jpexs_freadlngint( $f ); 
     672        $Ikona[ $p ][ "Info" ][ "ImageWidth" ] = jpexs_freadlngint( $f ); 
     673        $Ikona[ $p ][ "Info" ][ "ImageHeight" ] = jpexs_freadlngint( $f ); 
     674        $Ikona[ $p ][ "Info" ][ "NumberOfImagePlanes" ] = jpexs_freadword( $f ); 
     675        $Ikona[ $p ][ "Info" ][ "BitsPerPixel" ] = jpexs_freadword( $f ); 
     676        $Ikona[ $p ][ "Info" ][ "CompressionMethod" ] = jpexs_freadlngint( $f ); 
     677        $Ikona[ $p ][ "Info" ][ "SizeOfBitmap" ] = jpexs_freadlngint( $f ); 
     678        $Ikona[ $p ][ "Info" ][ "HorzResolution" ] = jpexs_freadlngint( $f ); 
     679        $Ikona[ $p ][ "Info" ][ "VertResolution" ] = jpexs_freadlngint( $f ); 
     680        $Ikona[ $p ][ "Info" ][ "NumColorUsed" ] = jpexs_freadlngint( $f ); 
     681        $Ikona[ $p ][ "Info" ][ "NumSignificantColors" ] = jpexs_freadlngint( $f ); 
     682         
     683         
     684        $biBitCount = $Ikona[ $p ][ "Info" ][ "BitsPerPixel" ]; 
     685         
     686        if ( $Ikona[ $p ][ "Info" ][ "BitsPerPixel" ] <= 8 ) { 
     687                $barev = pow( 2, $biBitCount ); 
     688                 
     689                for ( $b = 0; $b < $barev; $b++ ) { 
     690                        $Ikona[ $p ][ "Paleta" ][ $b ][ "b" ] = jpexs_freadbyte( $f ); 
     691                        $Ikona[ $p ][ "Paleta" ][ $b ][ "g" ] = jpexs_freadbyte( $f ); 
     692                        $Ikona[ $p ][ "Paleta" ][ $b ][ "r" ] = jpexs_freadbyte( $f ); 
     693                        jpexs_freadbyte( $f ); 
     694                } 
     695                 
     696                $Zbytek = ( 4 - ceil( ( $Width / ( 8 / $biBitCount ) ) ) % 4 ) % 4; 
     697                 
     698                 
     699                for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     700                        $jpexs_currentBit = 0; 
     701                        for ( $x = 0; $x < $Width; $x++ ) { 
     702                                $C = jpexs_freadbits( $f, $biBitCount ); 
     703                                $Ikona[ $p ][ "Data" ][ $x ][ $y ] = $C; 
     704                        } 
     705                         
     706                        if ( $jpexs_currentBit != 0 ) { 
     707                                jpexs_freadbyte( $f ); 
     708                        } 
     709                        for ( $g = 0; $g < $Zbytek; $g++ ) 
     710                                jpexs_freadbyte( $f ); 
     711                } 
     712                 
     713        } elseif ( $biBitCount == 24 ) { 
     714                $Zbytek = $Width % 4; 
     715                 
     716                for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     717                        for ( $x = 0; $x < $Width; $x++ ) { 
     718                                $B = jpexs_freadbyte( $f ); 
     719                                $G = jpexs_freadbyte( $f ); 
     720                                $R = jpexs_freadbyte( $f ); 
     721                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "r" ] = $R; 
     722                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "g" ] = $G; 
     723                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "b" ] = $B; 
     724                        } 
     725                        for ( $z = 0; $z < $Zbytek; $z++ ) 
     726                                jpexs_freadbyte( $f ); 
     727                } 
     728        } elseif ( $biBitCount == 32 ) { 
     729                $Zbytek = $Width % 4; 
     730                 
     731                for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     732                        for ( $x = 0; $x < $Width; $x++ ) { 
     733                                $B = jpexs_freadbyte( $f ); 
     734                                $G = jpexs_freadbyte( $f ); 
     735                                $R = jpexs_freadbyte( $f ); 
     736                                $Alpha = jpexs_freadbyte( $f ); 
     737                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "r" ] = $R; 
     738                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "g" ] = $G; 
     739                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "b" ] = $B; 
     740                                $Ikona[ $p ][ "Data" ][ $x ][ $y ][ "alpha" ] = $Alpha; 
     741                        } 
     742                        for ( $z = 0; $z < $Zbytek; $z++ ) 
     743                                jpexs_freadbyte( $f ); 
     744                } 
     745        } 
     746         
     747         
     748        //Maska 
     749        $Zbytek = ( 4 - ceil( ( $Width / ( 8 ) ) ) % 4 ) % 4; 
     750        for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     751                $jpexs_currentBit = 0; 
     752                for ( $x = 0; $x < $Width; $x++ ) { 
     753                        $C = jpexs_freadbits( $f, 1 ); 
     754                        $Ikona[ $p ][ "Maska" ][ $x ][ $y ] = $C; 
     755                } 
     756                if ( $jpexs_currentBit != 0 ) { 
     757                        jpexs_freadbyte( $f ); 
     758                } 
     759                for ( $g = 0; $g < $Zbytek; $g++ ) 
     760                        jpexs_freadbyte( $f ); 
     761        } 
     762        //-------------- 
     763         
     764        fclose( $f ); 
     765         
     766} 
     767 
     768function jpexs_GetIconsInfo( $filename ) { 
     769        global $jpexs_currentBit; 
     770         
     771        $f = fopen( $filename, "rb" ); 
     772         
     773        $Reserved = jpexs_freadword( $f ); 
     774        $Type = jpexs_freadword( $f ); 
     775        $Count = jpexs_freadword( $f ); 
     776        for ( $p = 0; $p < $Count; $p++ ) { 
     777                $Ikona[ $p ][ "Width" ] = jpexs_freadbyte( $f ); 
     778                $Ikona[ $p ][ "Height" ] = jpexs_freadbyte( $f ); 
     779                $Ikona[ $p ][ "ColorCount" ] = jpexs_freadword( $f ); 
     780                if ( $Ikona[ $p ][ "ColorCount" ] == 0 ) 
     781                        $Ikona[ $p ][ "ColorCount" ] = 256; 
     782                $Ikona[ $p ][ "Planes" ] = jpexs_freadword( $f ); 
     783                $Ikona[ $p ][ "BitCount" ] = jpexs_freadword( $f ); 
     784                $Ikona[ $p ][ "BytesInRes" ] = jpexs_freaddword( $f ); 
     785                $Ikona[ $p ][ "ImageOffset" ] = jpexs_freaddword( $f ); 
     786        } 
     787         
     788        if ( !feof( $f ) ): 
     789                for ( $p = 0; $p < $Count; $p++ ) { 
     790                        fseek( $f, $Ikona[ $p ][ "ImageOffset" ] + 14 ); 
     791                        $Ikona[ $p ][ "Info" ][ "BitsPerPixel" ] = jpexs_freadword( $f ); 
     792                } 
     793        endif; 
     794        fclose( $f ); 
     795        return $Ikona; 
     796} 
     797 
     798 
     799 
     800 
     801/** 
     802 * Reads image from a icon in exe file 
     803 * @param string $filename Target exefile 
     804 * @param int $icoIndex Index of the icon in exefile 
     805 * @param int $icoColorCount Icon color count (For multiple icons ico file) - 2,16,256, ICO_TRUE_COLOR, ICO_XP_COLOR or ICO_MAX_COLOR 
     806 * @param int $icoSize Icon width (For multiple icons ico file) or ICO_MAX_SIZE 
     807 * @param int $alphaBgR Background color R value for alpha-channel images (Default is White) 
     808 * @param int $alphaBgG Background color G value for alpha-channel images (Default is White) 
     809 * @param int $alphaBgB Background color B value for alpha-channel images (Default is White) 
     810 * @return resource Image resource or false on error 
     811 */ 
     812function imageCreateFromExeIco( $filename, $icoIndex, $icoColorCount = 16, $icoSize = 16, $alphaBgR = 255, $alphaBgG = 255, $alphaBgB = 255 ) { 
     813        $ok = saveExeIcon( $filename, "icotemp.dat", $icoIndex ); 
     814        if ( !$ok ): 
     815                $im = false; 
     816        else: 
     817                $im = imageCreateFromIco( "icotemp.dat", $icoColorCount, $icoSize, $alphaBgR, $alphaBgG, $alphaBgB ); 
     818                unlink( "icotemp.dat" ); 
     819        endif; 
     820        return $im; 
     821} 
     822 
     823 
     824/** 
     825 * Saves icon(s) from the exe file 
     826 * @global int $jpexs_StartOfRsrc Internal reserved variable 
     827 * @global int $jpexs_ImageBase Internal reserved variable 
     828 * @global int $jpexs_ResVirtualAddress Internal reserved variable 
     829 * @param string $filename Target exefile 
     830 * @param string $icoFileNameOrPath Filename to save ico or path (Default "") Path if you want more than 1 icon. If "", the filename is "$icoIndex.ico" 
     831 * @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. 
     832 * @return boolean True on successful save 
     833 */ 
     834function saveExeIcon( $filename, $icoFileNameOrPath = "", $iconIndex = -1 ) /*-1 for all,or can be array*/ { 
     835        global $jpexs_f, $jpexs_StartOfRsrc, $jpexs_ImageBase, $jpexs_ResVirtualAddress; 
     836        $jpexs_f = fopen( $filename, "r" ); 
     837        $MZ = fread( $jpexs_f, 2 ); 
     838        if ( $MZ != "MZ" ) 
     839                NotValidExe(); 
     840        fseek( $jpexs_f, 60 ); 
     841        $OffsetToNewHeader = jpexs_freaddword( $jpexs_f ); 
     842        fseek( $jpexs_f, $OffsetToNewHeader ); 
     843        $PE = fread( $jpexs_f, 2 ); 
     844        if ( $PE != "PE" ) 
     845                NotValidExe(); 
     846        fread( $jpexs_f, 4 ); 
     847        $NumberOfSections = jpexs_freadword( $jpexs_f ); 
     848        fseek( $jpexs_f, ftell( $jpexs_f ) + 12 ); 
     849        $SizeOfOptionalHeader = jpexs_freadword( $jpexs_f ); 
     850        $PosMagic = ftell( $jpexs_f ) + 2; 
     851        fseek( $jpexs_f, $PosMagic + $SizeOfOptionalHeader ); 
     852         
     853        for ( $p = 0; $p < $NumberOfSections; $p++ ): 
     854                $SectionName[ $p ] = trim( fread( $jpexs_f, 8 ) ); 
     855                $VirtualSize[ $p ] = jpexs_freaddword( $jpexs_f ); 
     856                $VirtualAddress[ $p ] = jpexs_freaddword( $jpexs_f ); 
     857                $PhysicalSize[ $p ] = jpexs_freaddword( $jpexs_f ); 
     858                $PhysicalOffset[ $p ] = jpexs_freaddword( $jpexs_f ); 
     859                fread( $jpexs_f, 16 ); 
     860                if ( $SectionName[ $p ] == ".rsrc" ): 
     861                        $jpexs_ResVirtualAddress = $VirtualAddress[ $p ]; 
     862                        fseek( $jpexs_f, $PhysicalOffset[ $p ] ); 
     863                        $jpexs_StartOfRsrc = $PhysicalOffset[ $p ]; 
     864                        jpexs_readResDirectoryEntry( $R, $PhysicalOffset[ $p ] ); 
     865                        $IconCount = null; 
     866                        $Ikona = null; 
     867                        while ( list( $key, $val ) = each( $R[ "Subdir" ] ) ): 
     868                                if ( $key == 14 ): 
     869                                        $r = 0; 
     870                                        while ( list( $key2, $val2 ) = each( $R[ "Subdir" ][ $key ][ "Subdir" ] ) ): 
     871                                                while ( list( $key3, $val3 ) = each( $R[ "Subdir" ][ $key ][ "Subdir" ][ $key2 ][ "Subdir" ] ) ): 
     872                                                        fseek( $jpexs_f, $val3[ "DataOffset" ] ); 
     873                                                        $Reserved = jpexs_freadword( $jpexs_f ); 
     874                                                        $Type = jpexs_freadword( $jpexs_f ); 
     875                                                        $ic = jpexs_freadword( $jpexs_f ); 
     876                                                        $IconCount[] = $ic; 
     877                                                        for ( $s = 0; $s < $ic; $s++ ) { 
     878                                                                $Ikona[ $r ][ $s ][ "Width" ] = jpexs_freadbyte( $jpexs_f ); 
     879                                                                $Ikona[ $r ][ $s ][ "Height" ] = jpexs_freadbyte( $jpexs_f ); 
     880                                                                $Ikona[ $r ][ $s ][ "ColorCount" ] = jpexs_freadword( $jpexs_f ); 
     881                                                                $Ikona[ $r ][ $s ][ "Planes" ] = jpexs_freadword( $jpexs_f ); 
     882                                                                $Ikona[ $r ][ $s ][ "BitCount" ] = jpexs_freadword( $jpexs_f ); 
     883                                                                $Ikona[ $r ][ $s ][ "BytesInRes" ] = jpexs_freaddword( $jpexs_f ); 
     884                                                                $Ikona[ $r ][ $s ][ "IconId" ] = jpexs_freadword( $jpexs_f ); 
     885                                                        } 
     886                                                        fseek( $jpexs_f, $val3[ "DataOffset" ] ); 
     887                                                        $r++; 
     888                                                endwhile; 
     889                                        endwhile; 
     890                                endif; 
     891                        endwhile; 
     892                         
     893                        reset( $R[ "Subdir" ] ); 
     894                         
     895                        while ( list( $key, $val ) = each( $R[ "Subdir" ] ) ): 
     896                                if ( $key == 3 ): 
     897                                        while ( list( $key2, $val2 ) = each( $R[ "Subdir" ][ $key ][ "Subdir" ] ) ): 
     898                                                for ( $r = 0; $r < count( $Ikona ); $r++ ): 
     899                                                        for ( $s = 0; $s < count( $Ikona[ $r ] ); $s++ ): 
     900                                                                while ( list( $key3, $val3 ) = each( $R[ "Subdir" ][ $key ][ "Subdir" ][ $Ikona[ $r ][ $s ][ "IconId" ] ][ "Subdir" ] ) ): 
     901                                                                        if ( ( $iconIndex == $r ) or ( $iconIndex == -1 ) or ( ( is_array( $iconIndex ) ) and ( in_array( $r, $iconIndex ) ) ) ): 
     902                                                                                fseek( $jpexs_f, $val3[ "DataOffset" ] ); 
     903                                                                                $Ikona[ $r ][ $s ][ "Data" ] = fread( $jpexs_f, $val3[ "DataSize" ] ); 
     904                                                                                $Ikona[ $r ][ $s ][ "DataSize" ] = $val3[ "DataSize" ]; 
     905                                                                        endif; 
     906                                                                endwhile; 
     907                                                        endfor; 
     908                                                endfor; 
     909                                        endwhile; 
     910                                endif; 
     911                        endwhile; 
     912                        $ok = false; 
     913                        for ( $r = 0; $r < count( $Ikona ); $r++ ): 
     914                                if ( ( $iconIndex == $r ) or ( $iconIndex == -1 ) or ( ( is_array( $iconIndex ) ) and ( in_array( $r, $iconIndex ) ) ) ): 
     915                                        $savefile = $icoFileNameOrPath; 
     916                                        if ( $icoFileNameOrPath == "" ) { 
     917                                                $savefile = "$r.ico"; 
     918                                        } else { 
     919                                                if ( ( $iconIndex == -1 ) or ( is_array( $iconIndex ) ) ) 
     920                                                        $savefile = $icoFileNameOrPath . "$r.ico"; 
     921                                        } 
     922                                        $f2 = fopen( $savefile, "w" ); 
     923                                        fwrite( $f2, jpexs_inttoword( 0 ) ); 
     924                                        fwrite( $f2, jpexs_inttoword( 1 ) ); 
     925                                        fwrite( $f2, jpexs_inttoword( count( $Ikona[ $r ] ) ) ); 
     926                                        $Offset = 6 + 16 * count( $Ikona[ $r ] ); 
     927                                        for ( $s = 0; $s < count( $Ikona[ $r ] ); $s++ ): 
     928                                                fwrite( $f2, jpexs_inttobyte( $Ikona[ $r ][ $s ][ "Width" ] ) ); 
     929                                                fwrite( $f2, jpexs_inttobyte( $Ikona[ $r ][ $s ][ "Height" ] ) ); 
     930                                                fwrite( $f2, jpexs_inttoword( $Ikona[ $r ][ $s ][ "ColorCount" ] ) ); 
     931                                                fwrite( $f2, jpexs_inttoword( $Ikona[ $r ][ $s ][ "Planes" ] ) ); 
     932                                                fwrite( $f2, jpexs_inttoword( $Ikona[ $r ][ $s ][ "BitCount" ] ) ); 
     933                                                fwrite( $f2, jpexs_inttodword( $Ikona[ $r ][ $s ][ "BytesInRes" ] ) ); 
     934                                                fwrite( $f2, jpexs_inttodword( $Offset ) ); 
     935                                                $Offset += $Ikona[ $r ][ $s ][ "DataSize" ]; 
     936                                        endfor; 
     937                                        for ( $s = 0; $s < count( $Ikona[ $r ] ); $s++ ): 
     938                                                fwrite( $f2, $Ikona[ $r ][ $s ][ "Data" ] ); 
     939                                        endfor; 
     940                                        fclose( $f2 ); 
     941                                        $ok = true; 
     942                                endif; 
     943                        endfor; 
     944                        return $ok; 
     945                endif; 
     946        endfor; 
     947         
     948        fclose( $jpexs_f ); 
     949} 
     950 
     951/** 
     952 * Internal function for reading exe icons 
     953 */ 
     954function jpexs_readResDirectoryEntry( &$parentRes, $offset ) { 
     955        global $jpexs_f, $jpexs_StartOfRsrc, $jpexs_ImageBase, $jpexs_ResVirtualAddress; 
     956        $lastPos = ftell( $jpexs_f ); 
     957        $Res = null; 
     958        fseek( $jpexs_f, $offset ); 
     959        //IMAGE_RESOURCE_DIRECTORY 
     960        $Characteristics = jpexs_freaddword( $jpexs_f ); 
     961        $TimeDateStamp = jpexs_freaddword( $jpexs_f ); 
     962        $MajorVersion = jpexs_freadword( $jpexs_f ); 
     963        $MinorVersion = jpexs_freadword( $jpexs_f ); 
     964        $NumberOfNamedEntries = jpexs_freadword( $jpexs_f ); 
     965        $NumberOfIdEntries = jpexs_freadword( $jpexs_f ); 
     966        for ( $q = 0; $q < $NumberOfNamedEntries + $NumberOfIdEntries; $q++ ): 
     967        //IMAGE_RESOURCE_DIRECTORY_ENTRY 
     968                $ResName = jpexs_freaddword( $jpexs_f ); 
     969                $lastPos2 = ftell( $jpexs_f ); 
     970                if ( $ResName >= 0x80000000 ): 
     971                //String Name 
     972                        $ResNameOffset = $ResName - 0x80000000; 
     973                        fseek( $jpexs_f, $jpexs_StartOfRsrc + $ResNameOffset ); 
     974                        $StringLength = jpexs_freadword( $jpexs_f ); 
     975                        $Identificator = ( fread( $jpexs_f, $StringLength * 2 ) ); 
     976                        fseek( $jpexs_f, $lastPos2 ); 
     977                else: 
     978                //Integer Id 
     979                        $Identificator = $ResName; 
     980                endif; 
     981                 
     982                $ResOffsetToData = jpexs_freaddword( $jpexs_f ); 
     983                if ( $ResOffsetToData >= 0x80000000 ): 
     984                        $SubResOffset = $ResOffsetToData - 0x80000000; 
     985                        jpexs_readResDirectoryEntry( $Res[ "$Identificator" ], $jpexs_StartOfRsrc + $SubResOffset ); 
     986                else: 
     987                        $RawDataOffset = $ResOffsetToData; 
     988                        $lastPos2 = ftell( $jpexs_f ); 
     989                        fseek( $jpexs_f, $jpexs_StartOfRsrc + $RawDataOffset ); 
     990                        //IMAGE_RESOURCE_DATA_ENTRY 
     991                        $OffsetToData = jpexs_freaddword( $jpexs_f ); 
     992                        $Res[ "$Identificator" ][ "DataOffset" ] = $jpexs_StartOfRsrc - $jpexs_ResVirtualAddress + $OffsetToData; 
     993                        $Res[ "$Identificator" ][ "DataSize" ] = jpexs_freaddword( $jpexs_f ); 
     994                        $CodePage = jpexs_freaddword( $jpexs_f ); 
     995                        $Reserved = jpexs_freaddword( $jpexs_f ); 
     996                        fseek( $jpexs_f, $lastPos2 ); 
     997                endif; 
     998        endfor; 
     999        fseek( $jpexs_f, $lastPos ); 
     1000        $parentRes[ "Subdir" ] = $Res; 
     1001} 
     1002 
     1003/** 
     1004 * Creates ico file from image resource(s) 
     1005 * @param resource|array $images Target Image resource (Can be array of image resources) 
     1006 * @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"); */ 
     1007function imageIco( $images, $filename = "" ) { 
     1008        if ( is_array( $images ) ) { 
     1009                $ImageCount = count( $images ); 
     1010                $Image = $images; 
     1011        } else { 
     1012                $Image[ 0 ] = $images; 
     1013                $ImageCount = 1; 
     1014        } 
     1015         
     1016         
     1017        $WriteToFile = false; 
     1018         
     1019        if ( $filename != "" ) { 
     1020                $WriteToFile = true; 
     1021        } 
     1022         
     1023         
     1024        $ret = ""; 
     1025         
     1026        $ret .= jpexs_inttoword( 0 ); //PASSWORD 
     1027        $ret .= jpexs_inttoword( 1 ); //SOURCE 
     1028        $ret .= jpexs_inttoword( $ImageCount ); //ICONCOUNT 
     1029         
     1030         
     1031        for ( $q = 0; $q < $ImageCount; $q++ ) { 
     1032                $img = $Image[ $q ]; 
     1033                 
     1034                $Width = imagesx( $img ); 
     1035                $Height = imagesy( $img ); 
     1036                 
     1037                $ColorCount = imagecolorstotal( $img ); 
     1038                 
     1039                $Transparent = imagecolortransparent( $img ); 
     1040                $IsTransparent = $Transparent != -1; 
     1041                 
     1042                 
     1043                if ( $IsTransparent ) 
     1044                        $ColorCount--; 
     1045                 
     1046                if ( $ColorCount == 0 ) { 
     1047                        $ColorCount = 0; 
     1048                        $BitCount = 24; 
     1049                } 
     1050                if ( ( $ColorCount > 0 ) and ( $ColorCount <= 2 ) ) { 
     1051                        $ColorCount = 2; 
     1052                        $BitCount = 1; 
     1053                } 
     1054                if ( ( $ColorCount > 2 ) and ( $ColorCount <= 16 ) ) { 
     1055                        $ColorCount = 16; 
     1056                        $BitCount = 4; 
     1057                } 
     1058                if ( ( $ColorCount > 16 ) and ( $ColorCount <= 256 ) ) { 
     1059                        $ColorCount = 0; 
     1060                        $BitCount = 8; 
     1061                } 
     1062                 
     1063                 
     1064                 
     1065                 
     1066                 
     1067                //ICONINFO: 
     1068                $ret .= jpexs_inttobyte( $Width ); // 
     1069                $ret .= jpexs_inttobyte( $Height ); // 
     1070                $ret .= jpexs_inttobyte( $ColorCount ); // 
     1071                $ret .= jpexs_inttobyte( 0 ); //RESERVED 
     1072                 
     1073                $Planes = 0; 
     1074                if ( $BitCount >= 8 ) 
     1075                        $Planes = 1; 
     1076                 
     1077                $ret .= jpexs_inttoword( $f, $Planes ); //PLANES 
     1078                if ( $BitCount >= 8 ) 
     1079                        $WBitCount = $BitCount; 
     1080                if ( $BitCount == 4 ) 
     1081                        $WBitCount = 0; 
     1082                if ( $BitCount == 1 ) 
     1083                        $WBitCount = 0; 
     1084                $ret .= jpexs_inttoword( $WBitCount ); //BITS 
     1085                 
     1086                $Zbytek = ( 4 - ( $Width / ( 8 / $BitCount ) ) % 4 ) % 4; 
     1087                $ZbytekMask = ( 4 - ( $Width / 8 ) % 4 ) % 4; 
     1088                 
     1089                $PalSize = 0; 
     1090                 
     1091                $Size = 40 + ( $Width / ( 8 / $BitCount ) + $Zbytek ) * $Height + ( ( $Width / 8 + $ZbytekMask ) * $Height ); 
     1092                if ( $BitCount < 24 ) 
     1093                        $Size += pow( 2, $BitCount ) * 4; 
     1094                $IconId = 1; 
     1095                $ret .= jpexs_inttodword( $Size ); //SIZE 
     1096                $OffSet = 6 + 16 * $ImageCount + $FullSize; 
     1097                $ret .= jpexs_inttodword( 6 + 16 * $ImageCount + $FullSize ); //OFFSET 
     1098                $FullSize += $Size; 
     1099                //------------- 
     1100                 
     1101        } 
     1102         
     1103         
     1104        for ( $q = 0; $q < $ImageCount; $q++ ) { 
     1105                $img = $Image[ $q ]; 
     1106                $Width = imagesx( $img ); 
     1107                $Height = imagesy( $img ); 
     1108                $ColorCount = imagecolorstotal( $img ); 
     1109                 
     1110                $Transparent = imagecolortransparent( $img ); 
     1111                $IsTransparent = $Transparent != -1; 
     1112                 
     1113                if ( $IsTransparent ) 
     1114                        $ColorCount--; 
     1115                if ( $ColorCount == 0 ) { 
     1116                        $ColorCount = 0; 
     1117                        $BitCount = 24; 
     1118                } 
     1119                if ( ( $ColorCount > 0 ) and ( $ColorCount <= 2 ) ) { 
     1120                        $ColorCount = 2; 
     1121                        $BitCount = 1; 
     1122                } 
     1123                if ( ( $ColorCount > 2 ) and ( $ColorCount <= 16 ) ) { 
     1124                        $ColorCount = 16; 
     1125                        $BitCount = 4; 
     1126                } 
     1127                if ( ( $ColorCount > 16 ) and ( $ColorCount <= 256 ) ) { 
     1128                        $ColorCount = 0; 
     1129                        $BitCount = 8; 
     1130                } 
     1131                 
     1132                 
     1133                 
     1134                //ICONS 
     1135                $ret .= jpexs_inttodword( 40 ); //HEADSIZE 
     1136                $ret .= jpexs_inttodword( $Width ); // 
     1137                $ret .= jpexs_inttodword( 2 * $Height ); // 
     1138                $ret .= jpexs_inttoword( 1 ); //PLANES 
     1139                $ret .= jpexs_inttoword( $BitCount ); // 
     1140                $ret .= jpexs_inttodword( 0 ); //Compress method 
     1141                 
     1142                 
     1143                $ZbytekMask = ( $Width / 8 ) % 4; 
     1144                 
     1145                $Zbytek = ( $Width / ( 8 / $BitCount ) ) % 4; 
     1146                $Size = ( $Width / ( 8 / $BitCount ) + $Zbytek ) * $Height + ( ( $Width / 8 + $ZbytekMask ) * $Height ); 
     1147                 
     1148                $ret .= jpexs_inttodword( $Size ); //SIZE 
     1149                 
     1150                $ret .= jpexs_inttodword( 0 ); //HPIXEL_M 
     1151                $ret .= jpexs_inttodword( 0 ); //V_PIXEL_M 
     1152                $ret .= jpexs_inttodword( $ColorCount ); //UCOLORS 
     1153                $ret .= jpexs_inttodword( 0 ); //DCOLORS 
     1154                //--------------- 
     1155                 
     1156                 
     1157                $CC = $ColorCount; 
     1158                if ( $CC == 0 ) 
     1159                        $CC = 256; 
     1160                 
     1161                if ( $BitCount < 24 ) { 
     1162                        $ColorTotal = imagecolorstotal( $img ); 
     1163                        if ( $IsTransparent ) 
     1164                                $ColorTotal--; 
     1165                         
     1166                        for ( $p = 0; $p < $ColorTotal; $p++ ) { 
     1167                                $color = imagecolorsforindex( $img, $p ); 
     1168                                $ret .= jpexs_inttobyte( $color[ "blue" ] ); 
     1169                                $ret .= jpexs_inttobyte( $color[ "green" ] ); 
     1170                                $ret .= jpexs_inttobyte( $color[ "red" ] ); 
     1171                                $ret .= jpexs_inttobyte( 0 ); //RESERVED 
     1172                        } 
     1173                         
     1174                        $CT = $ColorTotal; 
     1175                        for ( $p = $ColorTotal; $p < $CC; $p++ ) { 
     1176                                $ret .= jpexs_inttobyte( 0 ); 
     1177                                $ret .= jpexs_inttobyte( 0 ); 
     1178                                $ret .= jpexs_inttobyte( 0 ); 
     1179                                $ret .= jpexs_inttobyte( 0 ); //RESERVED 
     1180                        } 
     1181                } 
     1182                 
     1183                 
     1184                 
     1185                 
     1186                 
     1187                 
     1188                if ( $BitCount <= 8 ) { 
     1189                        for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     1190                                $bWrite = ""; 
     1191                                for ( $x = 0; $x < $Width; $x++ ) { 
     1192                                        $color = imagecolorat( $img, $x, $y ); 
     1193                                        if ( $color == $Transparent ) 
     1194                                                $color = imagecolorexact( $img, 0, 0, 0 ); 
     1195                                        if ( $color == -1 ) 
     1196                                                $color = 0; 
     1197                                        if ( $color > pow( 2, $BitCount ) - 1 ) 
     1198                                                $color = 0; 
     1199                                         
     1200                                        $bWrite .= jpexs_decbinx( $color, $BitCount ); 
     1201                                        if ( strlen( $bWrite ) == 8 ) { 
     1202                                                $ret .= jpexs_inttobyte( bindec( $bWrite ) ); 
     1203                                                $bWrite = ""; 
     1204                                        } 
     1205                                } 
     1206                                 
     1207                                if ( ( strlen( $bWrite ) < 8 ) and ( strlen( $bWrite ) != 0 ) ) { 
     1208                                        $sl = strlen( $bWrite ); 
     1209                                        for ( $t = 0; $t < 8 - $sl; $t++ ) 
     1210                                                $sl .= "0"; 
     1211                                        $ret .= jpexs_inttobyte( bindec( $bWrite ) ); 
     1212                                } 
     1213                                for ( $z = 0; $z < $Zbytek; $z++ ) 
     1214                                        $ret .= jpexs_inttobyte( 0 ); 
     1215                        } 
     1216                } 
     1217                 
     1218                 
     1219                 
     1220                if ( $BitCount >= 24 ) { 
     1221                        for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     1222                                for ( $x = 0; $x < $Width; $x++ ) { 
     1223                                        $color = imagecolorsforindex( $img, imagecolorat( $img, $x, $y ) ); 
     1224                                        $ret .= jpexs_inttobyte( $color[ "blue" ] ); 
     1225                                        $ret .= jpexs_inttobyte( $color[ "green" ] ); 
     1226                                        $ret .= jpexs_inttobyte( $color[ "red" ] ); 
     1227                                        if ( $BitCount == 32 ) 
     1228                                                $ret .= jpexs_inttobyte( 0 ); //Alpha for ICO_XP_COLORS 
     1229                                } 
     1230                                for ( $z = 0; $z < $Zbytek; $z++ ) 
     1231                                        $ret .= jpexs_inttobyte( 0 ); 
     1232                        } 
     1233                } 
     1234                 
     1235                 
     1236                //MASK 
     1237                 
     1238                for ( $y = $Height - 1; $y >= 0; $y-- ) { 
     1239                        $byteCount = 0; 
     1240                        $bOut = ""; 
     1241                        for ( $x = 0; $x < $Width; $x++ ) { 
     1242                                if ( ( $Transparent != -1 ) and ( imagecolorat( $img, $x, $y ) == $Transparent ) ) { 
     1243                                        $bOut .= "1"; 
     1244                                } else { 
     1245                                        $bOut .= "0"; 
     1246                                } 
     1247                        } 
     1248                        for ( $p = 0; $p < strlen( $bOut ); $p += 8 ) { 
     1249                                $byte = bindec( substr( $bOut, $p, 8 ) ); 
     1250                                $byteCount++; 
     1251                                $ret .= jpexs_inttobyte( $byte ); 
     1252                        } 
     1253                        $Zbytek = $byteCount % 4; 
     1254                        for ( $z = 0; $z < $Zbytek; $z++ ) { 
     1255                                $ret .= jpexs_inttobyte( 0xff ); 
     1256                        } 
     1257                } 
     1258                 
     1259                //------------------ 
     1260                 
     1261        } //q 
     1262         
     1263         
     1264         
     1265         
     1266         
     1267        if ( $WriteToFile ) { 
     1268                $f = fopen( $filename, "w" ); 
     1269                fwrite( $f, $ret ); 
     1270                fclose( $f ); 
     1271        } else { 
     1272                echo $ret; 
     1273        } 
     1274         
     1275} 
     1276 
     1277 
     1278 
     1279 
     1280/* 
     1281 * Internal functions: 
     1282 *------------------------- 
     1283 * jpexs_inttobyte($n) - returns chr(n) 
     1284 * jpexs_inttodword($n) - returns dword (n) 
     1285 * jpexs_inttoword($n) - returns word(n) 
     1286 * jpexs_freadbyte($file) - reads 1 byte from $file 
     1287 * jpexs_freadword($file) - reads 2 bytes (1 word) from $file 
     1288 * jpexs_freaddword($file) - reads 4 bytes (1 dword) from $file 
     1289 * jpexs_freadlngint($file) - same as freaddword($file) 
     1290 * jpexs_decbin8($d) - returns binary string of d zero filled to 8 
     1291 * jpexs_RetBits($byte,$start,$len) - returns bits $start->$start+$len from $byte 
     1292 * jpexs_freadbits($file,$count) - reads next $count bits from $file 
     1293 */ 
     1294 
     1295 
     1296function jpexs_decbin8( $d ) { 
     1297        return jpexs_decbinx( $d, 8 ); 
     1298} 
     1299 
     1300function jpexs_decbinx( $d, $n ) { 
     1301        $bin = decbin( $d ); 
     1302        $sbin = strlen( $bin ); 
     1303        for ( $j = 0; $j < $n - $sbin; $j++ ) 
     1304                $bin = "0$bin"; 
     1305        return $bin; 
     1306} 
     1307 
     1308function jpexs_retBits( $byte, $start, $len ) { 
     1309        $bin = jpexs_decbin8( $byte ); 
     1310        $r = bindec( substr( $bin, $start, $len ) ); 
     1311        return $r; 
     1312         
     1313} 
     1314 
     1315 
     1316 
     1317$jpexs_currentBit = 0; 
     1318function jpexs_freadbits( $f, $count ) { 
     1319        global $jpexs_currentBit, $jpexs_SMode; 
     1320        $Byte = jpexs_freadbyte( $f ); 
     1321        $LastCBit = $jpexs_currentBit; 
     1322        $jpexs_currentBit += $count; 
     1323        if ( $jpexs_currentBit == 8 ) { 
     1324                $jpexs_currentBit = 0; 
     1325        } else { 
     1326                fseek( $f, ftell( $f ) - 1 ); 
     1327        } 
     1328        return jpexs_retBits( $Byte, $LastCBit, $count ); 
     1329} 
     1330 
     1331 
     1332function jpexs_freadbyte( $f ) { 
     1333        return ord( fread( $f, 1 ) ); 
     1334} 
     1335 
     1336function jpexs_freadword( $f ) { 
     1337        $b1 = jpexs_freadbyte( $f ); 
     1338        $b2 = jpexs_freadbyte( $f ); 
     1339        return $b2 * 256 + $b1; 
     1340} 
     1341 
     1342 
     1343function jpexs_freadlngint( $f ) { 
     1344        return jpexs_freaddword( $f ); 
     1345} 
     1346 
     1347function jpexs_freaddword( $f ) { 
     1348        $b1 = jpexs_freadword( $f ); 
     1349        $b2 = jpexs_freadword( $f ); 
     1350        return $b2 * 65536 + $b1; 
     1351} 
     1352 
     1353function jpexs_inttobyte( $n ) { 
     1354        return chr( $n ); 
     1355} 
     1356 
     1357function jpexs_inttodword( $n ) { 
     1358        return chr( $n & 255 ) . chr( ( $n >> 8 ) & 255 ) . chr( ( $n >> 16 ) & 255 ) . chr( ( $n >> 24 ) & 255 ); 
     1359} 
     1360 
     1361function jpexs_inttoword( $n ) { 
     1362        return chr( $n & 255 ) . chr( ( $n >> 8 ) & 255 ); 
     1363} 
     1364 No newline at end of file 
  • wp-admin/js/wp-favicon.dev.js

     
     1(function($){ 
     2    $('#faviconfile').change(function(){  
     3        // check the file extension 
     4        if ( $.inArray( $(this).val().split('.').pop().toLowerCase(), ['ico', 'png', 'bmp', 'jpg', 'jpeg'] ) < 0 ) { 
     5            $('#favicon-invalid-filetype-error').show(); 
     6                        $('#faviconupload')[0].reset(); 
     7                } 
     8        else 
     9        { 
     10            $('#faviconupload').submit(); 
     11        } 
     12    }); 
     13 
     14})(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    <?php settings_fields('favicon_upload') ?> 
     95        <table class="form-table"> 
     96                <tr valign="top"> 
     97                        <th scope="row"><label for="sitefavicon"><?php _e('Favicon') ?></label></th> 
     98                        <td> 
     99                                <?php 
     100                                        // display the icon and the remove link if appropriate 
     101                                        if ( has_custom_favicon() ){ 
     102                                                if ( $thumbnail = get_favicon_img() ) echo $thumbnail; 
     103                                                echo "\t" . '<input type="submit" name="REMOVE_FAVICON" value="Remove Favicon" id="remove-favicon-button" />'; 
     104                                                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>'; 
     105                                        } else { 
     106                                ?> 
     107                                        <input class="button" name="avatarfile" type="file" id="faviconfile" size="35" /> 
     108                                        <p class="submit no-js hide-if-js"><input type="submit" name="Submit" value="Upload Image &raquo;" id="faviconsubmit" /></p> 
     109                                        <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> 
     110                                        <span id="favicon-invalid-filetype-error"><?php _e( 'Please only upload files in the following formats: .ico, .png, .bmp, .jpg' ) ?></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

     
    17731773                'png' => 'image/png', 
    17741774                'bmp' => 'image/bmp', 
    17751775                'tif|tiff' => 'image/tiff', 
    1776                 'ico' => 'image/x-icon', 
     1776                'ico' => 'image/vnd.microsoft.icon', 
    17771777                'asf|asx|wax|wmv|wmx' => 'video/asf', 
    17781778                'avi' => 'video/avi', 
    17791779                '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        $favicon_uri = get_site_favicon_uri(); 
     1610        $ie_favicon_uri = get_site_favicon_uri( 'ico' ); 
     1611 
     1612        $content = ""; 
     1613        if (! empty( $favicon_uri ) ){ 
     1614                $content .= "\n\n<!--favicon (via 'wp_head' action) -->\n"; 
     1615 
     1616                if (! empty( $ie_favicon_uri )) $content .= <<<IE_FAVICON_1 
     1617<!--[if IE]> 
     1618        <link rel="shortcut icon" href="{$ie_favicon_uri}" /> 
     1619<![endif]--> 
     1620<!--[if !IE]>-->\n 
     1621IE_FAVICON_1; 
     1622 
     1623                $content .= "\t<link href=\"{$favicon_uri}\" rel=\"icon\" type=\"image/png\" />\n"; 
     1624                 
     1625                if (! empty( $ie_favicon_uri )) $content .= "<!--<![endif]-->"; 
     1626                $content .= "\n<!-- /favicon -->\n\n"; 
     1627    } 
     1628        return $content; 
     1629} 
     1630 
     1631/** 
     1632 * Get the attachment post object associated with the current site favicon, based on the 'sitefavicon' option 
     1633 *  
     1634 * @param string $format Default 'png'. Format of the file we're looking for 
     1635 * @return object If found, returns the post object; if not, a WP_Error object 
     1636 */ 
     1637function get_site_favicon_attachment( $format = 'png' ){ 
     1638        $favicon_basename = get_option ( 'sitefavicon' );  
     1639         
     1640        if ( ! empty( $favicon_basename ) ) { 
     1641                $favicon_fullname = $favicon_basename . '-' . $format; 
     1642                 
     1643                $posts = get_posts( array( 'name' => $favicon_fullname, 'post_type' => 'attachment' ) ); 
     1644                if ( $posts[0] ){ 
     1645                        return $posts[0]; 
     1646                } else { 
     1647                        return new WP_Error( 'attachment_missing', __( "No attachment for '$favicon_fullname' was found." ) ); 
     1648                } 
     1649        } else { 
     1650                return new WP_Error( 'not_defined', __( "No favicon file provided." ) ); 
     1651        } 
     1652} 
     1653 
     1654/** 
     1655 * Returns the URI for the site's favicon based on the option set in  Admin > Settings > General. 
     1656 *  
     1657 * @param string $format png|ico default 'png'. Use 'ico' for serving up an IE-compatible ICO file 
     1658 * @return string fully qualified URI  
     1659 */ 
     1660function get_site_favicon_uri( $format = 'png' ){ 
     1661        /** @TODO provide error checking for validity of $format and $size */ 
     1662        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1663         
     1664        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1665        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1666                return wp_get_attachment_url( $favicon_attachment->ID ); 
     1667        } 
     1668         
     1669        // We get here because of an error condition 
     1670        /** @TODO default to the theme's favicon **/ 
     1671        // ATM do nothing (so URI is blank, rather than a WP_Error) 
     1672} 
     1673 
     1674/** 
     1675 * Gets the path to the favicon file, or returns a WP_Error 
     1676 * @param string $format Default 'png' 
     1677 * @return mixed File string or WP_Error object  
     1678 */ 
     1679function get_site_favicon_file( $format = 'png' ){ 
     1680        $favicon_attachment = get_site_favicon_attachment( $format ); 
     1681         
     1682        /** @TODO provide the ability to define a 'default' favicon that would be distributed with fresh WP installations */ 
     1683        if ( ! is_wp_error( $favicon_attachment ) ) { 
     1684                $file = get_attached_file( $favicon_attachment->ID ); 
     1685                if ( file_exists( $file ) ) return $file; 
     1686                else return new WP_Error( 'file_missing', __( 'Favicon image file missing.' ) ); 
     1687        } else { 
     1688                return $favicon_attachment; // returns the WP_Error object 
     1689        } 
     1690} 
     1691 
     1692/** 
     1693 * Returns true or false depending on whether a custom favicon has been defined in Admin 
     1694 * @return boolean  
     1695 */ 
     1696function has_custom_favicon(){ 
     1697        return ( get_option ( 'sitefavicon' ) && ! is_wp_error( get_site_favicon_file() ) ); 
     1698} 
     1699 
     1700/** 
     1701 * Returns an HTML <img> tag populated with the site favicon, in the format specified (usually PNG) 
     1702 * @param string $format Default 'png'. Valid values are 'png', 'bmp' (note 'ico' is NOT valid) 
     1703 * @return mixed Returns HTML <img> tag or WP_Error if invalid format given. Returns nothing if the file is missing.  
     1704 */ 
     1705function get_favicon_img( $format = 'png' ){ 
     1706        if (in_array( strtolower( $format ), array( 'png', 'bmp' ) ) ){ 
     1707                // Does the file actually exist? 
     1708                $file = get_site_favicon_file( $format ); 
     1709                if (! is_wp_error( $file ) && file_exists( $file ) ){ 
     1710                        $src = get_site_favicon_uri( $format ); 
     1711                        if (!is_wp_error( $src ) ){ 
     1712                                return '<img src="' . $src . '" class="favicon" alt="' . _x( 'Site favicon thumbnail', 'Thumbnail image accessibility text' ) .'" />'; 
     1713                        } 
     1714                } 
     1715        } else { 
     1716                return new WP_Error( 'invalid_file_format', __( 'Invalid file format. Valid formats are "png", "bmp".' ) ); 
     1717        } 
     1718} 
     1719 
     1720/** 
    15901721 * Display the links to the general feeds. 
    15911722 * 
    15921723 * @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 );