WordPress.org

Make WordPress Core

Ticket #6821: 6821.diff

File 6821.diff, 43.2 KB (added by DH-Shredder, 20 months ago)

Initial Abstraction of GD with WP_Image_Editor

  • wp-admin/includes/image-edit.php

    diff --git wp-admin/includes/image-edit.php wp-admin/includes/image-edit.php
    index d2d6dc2..a0423f3 100644
    function wp_image_editor($post_id, $msg = false) { 
    197197<?php 
    198198} 
    199199 
    200 function wp_stream_image($image, $mime_type, $post_id) { 
    201         $image = apply_filters('image_save_pre', $image, $post_id); 
    202  
    203         switch ( $mime_type ) { 
    204                 case 'image/jpeg': 
    205                         header('Content-Type: image/jpeg'); 
    206                         return imagejpeg($image, null, 90); 
    207                 case 'image/png': 
    208                         header('Content-Type: image/png'); 
    209                         return imagepng($image); 
    210                 case 'image/gif': 
    211                         header('Content-Type: image/gif'); 
    212                         return imagegif($image); 
    213                 default: 
    214                         return false; 
    215         } 
     200/** 
     201 * Streams image in WP_Image_Editor to browser. 
     202 * Provided for backcompat reasons 
     203 * 
     204 * @param WP_Image_Editor $image 
     205 * @param string $mime_type 
     206 * @param int $post_id 
     207 * @return boolean 
     208 */ 
     209function wp_stream_image( $image, $mime_type, $post_id ) { 
     210        $image = apply_filters('image_editor_save_pre', $image, $post_id); 
     211 
     212        if ( ! is_resource( $image ) ) { 
     213                $image->stream(); 
     214 
     215    } else { 
     216                _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 
     217 
     218                $image = apply_filters('image_save_pre', $image, $post_id); 
     219 
     220                switch ( $mime_type ) { 
     221                    case 'image/jpeg': 
     222                            header( 'Content-Type: image/jpeg' ); 
     223                            return imagejpeg( $image, null, 90 ); 
     224                    case 'image/png': 
     225                            header( 'Content-Type: image/png' ); 
     226                            return imagepng( $image ); 
     227                    case 'image/gif': 
     228                            header( 'Content-Type: image/gif' ); 
     229                            return imagegif( $image ); 
     230                    default: 
     231                                return false; 
     232                } 
     233    } 
    216234} 
    217235 
    218 function wp_save_image_file($filename, $image, $mime_type, $post_id) { 
    219         $image = apply_filters('image_save_pre', $image, $post_id); 
    220         $saved = apply_filters('wp_save_image_file', null, $filename, $image, $mime_type, $post_id); 
    221         if ( null !== $saved ) 
    222                 return $saved; 
    223  
    224         switch ( $mime_type ) { 
    225                 case 'image/jpeg': 
    226                         return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) ); 
    227                 case 'image/png': 
    228                         return imagepng($image, $filename); 
    229                 case 'image/gif': 
    230                         return imagegif($image, $filename); 
    231                 default: 
    232                         return false; 
     236/** 
     237 * @TODO: Public function that accepts GD images as input. 
     238 * @TODO: Add mime_type support to WP_Image_Editor 
     239 * 
     240 * @param string $filename 
     241 * @param WP_Image_Editor $image 
     242 * @param string $mime_type 
     243 * @param int $post_id 
     244 * @return boolean 
     245 */ 
     246function wp_save_image_file( $filename, $image, $mime_type, $post_id ) { 
     247        if ( ! is_resource( $image ) ) { 
     248                $image = apply_filters('image_editor_save_pre', $image, $post_id); 
     249                $saved = apply_filters('wp_save_image_editor_file', null, $filename, $image, $mime_type, $post_id); 
     250 
     251                if ( null !== $saved ) 
     252                        return $saved; 
     253 
     254                return $image->save( $filename ); 
     255        } else { 
     256                _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 
     257 
     258                $image = apply_filters('image_save_pre', $image, $post_id); 
     259                $saved = apply_filters('wp_save_image_file', null, $filename, $image, $mime_type, $post_id); 
     260 
     261                if ( null !== $saved ) 
     262                        return $saved; 
     263 
     264                switch ( $mime_type ) { 
     265                        case 'image/jpeg': 
     266                                return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) ); 
     267                        case 'image/png': 
     268                                return imagepng( $image, $filename ); 
     269                        case 'image/gif': 
     270                                return imagegif( $image, $filename ); 
     271                        default: 
     272                                return false; 
     273                } 
    233274        } 
    234275} 
    235276 
    function _image_get_preview_ratio($w, $h) { 
    238279        return $max > 400 ? (400 / $max) : 1; 
    239280} 
    240281 
     282// @TODO: Returns GD resource, but is NOT public 
    241283function _rotate_image_resource($img, $angle) { 
    242284        if ( function_exists('imagerotate') ) { 
    243285                $rotated = imagerotate($img, $angle, 0); 
    function _rotate_image_resource($img, $angle) { 
    249291        return $img; 
    250292} 
    251293 
     294/** 
     295 * @TODO: Only used within image_edit_apply_changes 
     296 *                and receives/returns GD Resource. 
     297 *                Consider removal. 
     298 * 
     299 * @param GD_Resource $img 
     300 * @param boolean $horz 
     301 * @param boolean $vert 
     302 * @return GD_Resource 
     303 */ 
    252304function _flip_image_resource($img, $horz, $vert) { 
    253305        $w = imagesx($img); 
    254306        $h = imagesy($img); 
    function _flip_image_resource($img, $horz, $vert) { 
    267319        return $img; 
    268320} 
    269321 
     322/** 
     323 * @TODO: Only used within image_edit_apply_changes 
     324 *                and receives/returns GD Resource. 
     325 *                Consider removal. 
     326 * 
     327 * @param GD_Resource $img 
     328 * @param float $x 
     329 * @param float $y 
     330 * @param float $w 
     331 * @param float $h 
     332 * @return GD_Resource 
     333 */ 
    270334function _crop_image_resource($img, $x, $y, $w, $h) { 
    271335        $dst = wp_imagecreatetruecolor($w, $h); 
    272336        if ( is_resource($dst) ) { 
    function _crop_image_resource($img, $x, $y, $w, $h) { 
    278342        return $img; 
    279343} 
    280344 
    281 function image_edit_apply_changes($img, $changes) { 
     345/** 
     346 * Performs group of changes on Editor specified. 
     347 * 
     348 * @param WP_Image_Editor $image 
     349 * @param type $changes 
     350 * @return GD Image 
     351 */ 
     352function image_edit_apply_changes( $image, $changes ) { 
     353        if ( is_resource( $image ) ) 
     354                _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 
    282355 
    283356        if ( !is_array($changes) ) 
    284                 return $img; 
     357                return $image; 
    285358 
    286359        // expand change operations 
    287360        foreach ( $changes as $key => $obj ) { 
    function image_edit_apply_changes($img, $changes) { 
    326399        } 
    327400 
    328401        // image resource before applying the changes 
    329         $img = apply_filters('image_edit_before_change', $img, $changes); 
     402        if ( ! is_resource( $image ) ) 
     403                $image = apply_filters('wp_image_editor_before_change', $image, $changes); 
     404        else 
     405                $image = apply_filters('image_edit_before_change', $image, $changes); 
    330406 
    331407        foreach ( $changes as $operation ) { 
    332408                switch ( $operation->type ) { 
    333409                        case 'rotate': 
    334                                 if ( $operation->angle != 0 ) 
    335                                         $img = _rotate_image_resource($img, $operation->angle); 
     410                                if ( $operation->angle != 0 ) { 
     411                                        if ( ! is_resource( $image ) ) 
     412                                                $image->rotate( $operation->angle ); 
     413                                        else 
     414                                                $image = _rotate_image_resource( $image, $operation->angle ); 
     415                                } 
    336416                                break; 
    337417                        case 'flip': 
    338418                                if ( $operation->axis != 0 ) 
    339                                         $img = _flip_image_resource($img, ($operation->axis & 1) != 0, ($operation->axis & 2) != 0); 
     419                                        if ( ! is_resource( $image ) ) 
     420                                                $image->flip( ($operation->axis & 1) != 0, ($operation->axis & 2) != 0 ); 
     421                                        else 
     422                                                $image = _flip_image_resource( $image, ( $operation->axis & 1 ) != 0, ( $operation->axis & 2 ) != 0 ); 
    340423                                break; 
    341424                        case 'crop': 
    342425                                $sel = $operation->sel; 
    343                                 $scale = 1 / _image_get_preview_ratio( imagesx($img), imagesy($img) ); // discard preview scaling 
    344                                 $img = _crop_image_resource($img, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale); 
     426 
     427                                if ( ! is_resource( $image ) ) { 
     428                                        $size = $image->get_size(); 
     429                                        $w = $size['width']; 
     430                                        $h = $size['height']; 
     431 
     432                                        $scale = 1 / _image_get_preview_ratio( $w, $h ); // discard preview scaling 
     433                                        $image->crop( $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); 
     434                                } else { 
     435                                        $scale = 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // discard preview scaling 
     436                                        $image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); 
     437                                } 
    345438                                break; 
    346439                } 
    347440        } 
    348441 
    349         return $img; 
     442        return $image; 
    350443} 
    351444 
     445 
     446/** 
     447 * Streams image in post to browser, along with enqueued changes 
     448 * in $_REQUEST['history'] 
     449 * 
     450 * @param int $post_id 
     451 * @return boolean 
     452 */ 
    352453function stream_preview_image($post_id) { 
    353454        $post = get_post($post_id); 
    354455        @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 
    355         $img = load_image_to_edit( $post_id, $post->post_mime_type, array(400, 400) ); 
    356456 
    357         if ( !is_resource($img) ) 
    358                 return false; 
     457        $img = WP_Image_Editor::get_instance( _load_image_to_edit_path( $post_id ) ); 
     458 
     459    if ( ! $img ) 
     460        return false; 
    359461 
    360462        $changes = !empty($_REQUEST['history']) ? json_decode( stripslashes($_REQUEST['history']) ) : null; 
    361463        if ( $changes ) 
    362                 $img = image_edit_apply_changes($img, $changes); 
     464                $img = image_edit_apply_changes( $img, $changes ); 
    363465 
    364466        // scale the image 
    365         $w = imagesx($img); 
    366         $h = imagesy($img); 
    367         $ratio = _image_get_preview_ratio($w, $h); 
     467        $size = $img->get_size(); 
     468        $w = $size['width']; 
     469        $h = $size['height']; 
     470 
     471        $ratio = _image_get_preview_ratio( $w, $h ); 
    368472        $w2 = $w * $ratio; 
    369473        $h2 = $h * $ratio; 
    370474 
    371         $preview = wp_imagecreatetruecolor($w2, $h2); 
    372         imagecopyresampled( $preview, $img, 0, 0, 0, 0, $w2, $h2, $w, $h ); 
    373         wp_stream_image($preview, $post->post_mime_type, $post_id); 
    374  
    375         imagedestroy($preview); 
    376         imagedestroy($img); 
     475        $img->resize( $w2, $h2 ); 
     476        wp_stream_image( $img, $post->post_mime_type, $post_id ); 
    377477        return true; 
    378478} 
    379479 
    function wp_restore_image($post_id) { 
    452552        return $msg; 
    453553} 
    454554 
    455 function wp_save_image($post_id) { 
     555/** 
     556 * Saves image to post along with enqueued changes 
     557 * in $_REQUEST['history'] 
     558 * 
     559 * @param int $post_id 
     560 * @return \stdClass 
     561 */ 
     562function wp_save_image( $post_id ) { 
    456563        $return = new stdClass; 
    457564        $success = $delete = $scaled = $nocrop = false; 
    458         $post = get_post($post_id); 
    459         @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 
    460         $img = load_image_to_edit($post_id, $post->post_mime_type); 
     565        $post = get_post( $post_id ); 
    461566 
    462         if ( !is_resource($img) ) { 
     567        $img = WP_Image_Editor::get_instance( _load_image_to_edit_path( $post_id, 'full' ) ); 
     568        if ( !$img ) { 
    463569                $return->error = esc_js( __('Unable to create new image.') ); 
    464570                return $return; 
    465571        } 
    function wp_save_image($post_id) { 
    470576        $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do']; 
    471577 
    472578        if ( $scale && $fwidth > 0 && $fheight > 0 ) { 
    473                 $sX = imagesx($img); 
    474                 $sY = imagesy($img); 
     579                $size = $img->get_size(); 
     580                $sX = $size['width']; 
     581                $sY = $size['height']; 
    475582 
    476583                // check if it has roughly the same w / h ratio 
    477584                $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2); 
    478585                if ( -0.1 < $diff && $diff < 0.1 ) { 
    479586                        // scale the full size image 
    480                         $dst = wp_imagecreatetruecolor($fwidth, $fheight); 
    481                         if ( imagecopyresampled( $dst, $img, 0, 0, 0, 0, $fwidth, $fheight, $sX, $sY ) ) { 
    482                                 imagedestroy($img); 
    483                                 $img = $dst; 
     587                        if ( $img->resize( $fwidth, $fheight ) ) 
    484588                                $scaled = true; 
    485                         } 
    486589                } 
    487590 
    488591                if ( !$scaled ) { 
    function wp_save_image($post_id) { 
    553656                if ( $tag ) 
    554657                        $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']); 
    555658 
    556                 $success = update_attached_file($post_id, $new_path); 
     659                $success = update_attached_file( $post_id, $new_path ); 
     660 
     661                $meta['file'] = _wp_relative_upload_path( $new_path ); 
    557662 
    558                 $meta['file'] = _wp_relative_upload_path($new_path); 
    559                 $meta['width'] = imagesx($img); 
    560                 $meta['height'] = imagesy($img); 
     663                $size = $img->get_size(); 
     664                $meta['width'] = $size['width']; 
     665                $meta['height'] = $size['height']; 
    561666 
    562667                list ( $uwidth, $uheight ) = wp_constrain_dimensions($meta['width'], $meta['height'], 128, 96); 
    563668                $meta['hwstring_small'] = "height='$uheight' width='$uwidth'"; 
    function wp_save_image($post_id) { 
    575680                $success = $delete = $nocrop = true; 
    576681        } 
    577682 
    578         if ( isset($sizes) ) { 
     683        if ( isset( $sizes ) ) { 
     684                $_sizes = array(); 
     685 
    579686                foreach ( $sizes as $size ) { 
    580687                        $tag = false; 
    581                         if ( isset($meta['sizes'][$size]) ) { 
     688                        if ( isset( $meta['sizes'][$size] ) ) { 
    582689                                if ( isset($backup_sizes["$size-orig"]) ) { 
    583690                                        if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes["$size-orig"]['file'] != $meta['sizes'][$size]['file'] ) 
    584691                                                $tag = "$size-$suffix"; 
    function wp_save_image($post_id) { 
    591698                        } 
    592699 
    593700                        $crop = $nocrop ? false : get_option("{$size}_crop"); 
    594                         $resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), $crop ); 
    595  
    596                         if ( $resized ) 
    597                                 $meta['sizes'][$size] = $resized; 
    598                         else 
    599                                 unset($meta['sizes'][$size]); 
     701                        $_sizes[ $size ] = array( 'width' => get_option("{$size}_size_w"), 'height' => get_option("{$size}_size_h"), 'crop' => $crop ); 
    600702                } 
     703 
     704                $meta['sizes'] = $img->multi_resize( $_sizes ); 
    601705        } 
    602706 
     707        unset( $img ); 
     708 
    603709        if ( $success ) { 
    604                 wp_update_attachment_metadata($post_id, $meta); 
     710                wp_update_attachment_metadata( $post_id, $meta ); 
    605711                update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes); 
    606712 
    607713                if ( $target == 'thumbnail' || $target == 'all' || $target == 'full' ) { 
    function wp_save_image($post_id) { 
    617723 
    618724        if ( $delete ) { 
    619725                $delpath = apply_filters('wp_delete_file', $new_path); 
    620                 @unlink($delpath); 
     726                @unlink( $delpath ); 
    621727        } 
    622728 
    623         imagedestroy($img); 
    624  
    625729        $return->msg = esc_js( __('Image saved') ); 
    626730        return $return; 
    627731} 
  • wp-admin/includes/image.php

    diff --git wp-admin/includes/image.php wp-admin/includes/image.php
    index 8048387..6dbc39f 100644
    function wp_create_thumbnail( $file, $max_side, $deprecated = '' ) { 
    4343 * @param string $dst_file Optional. The destination file to write to. 
    4444 * @return string|WP_Error|false New filepath on success, WP_Error or false on failure. 
    4545 */ 
    46 function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) { 
    47         if ( is_numeric( $src ) ) { // Handle int as attachment ID 
    48                 $src_file = get_attached_file( $src ); 
     46function wp_crop_image( $src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) { 
     47        if ( is_numeric( $src_file ) ) { // Handle int as attachment ID 
     48                $src_file = get_attached_file( $src_file ); 
    4949                if ( ! file_exists( $src_file ) ) { 
    5050                        // If the file doesn't exist, attempt a url fopen on the src link. 
    5151                        // This can occur with certain file replication plugins. 
    52                         $post = get_post( $src ); 
    53                         $image_type = $post->post_mime_type; 
    54                         $src = load_image_to_edit( $src, $post->post_mime_type, 'full' ); 
    55                 } else { 
    56                         $size = @getimagesize( $src_file ); 
    57                         $image_type = ( $size ) ? $size['mime'] : ''; 
    58                         $src = wp_load_image( $src_file ); 
     52                        $src_file = _load_image_to_edit_path( $src_file, 'full' ); 
    5953                } 
    60         } else { 
    61                 $size = @getimagesize( $src ); 
    62                 $image_type = ( $size ) ? $size['mime'] : ''; 
    63                 $src = wp_load_image( $src ); 
    64         } 
    65  
    66         if ( ! is_resource( $src ) ) 
    67                 return new WP_Error( 'error_loading_image', $src, $src_file ); 
    68  
    69         $dst = wp_imagecreatetruecolor( $dst_w, $dst_h ); 
    70  
    71         if ( $src_abs ) { 
    72                 $src_w -= $src_x; 
    73                 $src_h -= $src_y; 
    7454        } 
    7555 
    76         if ( function_exists( 'imageantialias' ) ) 
    77                 imageantialias( $dst, true ); 
     56        $editor = WP_Image_Editor::get_instance( $src_file ); 
     57        $src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs ); 
    7858 
    79         imagecopyresampled( $dst, $src, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); 
    80  
    81         imagedestroy( $src ); // Free up memory 
     59        if ( ! $src ) 
     60                return new WP_Error( 'error_loading_image', '', $src_file ); 
    8261 
    8362        if ( ! $dst_file ) 
    8463                $dst_file = str_replace( basename( $src_file ), 'cropped-' . basename( $src_file ), $src_file ); 
    8564 
    86         if ( 'image/png' != $image_type ) 
    87                 $dst_file = preg_replace( '/\\.[^\\.]+$/', '.jpg', $dst_file ); 
    88  
    8965        // The directory containing the original file may no longer exist when 
    9066        // using a replication plugin. 
    9167        wp_mkdir_p( dirname( $dst_file ) ); 
    9268 
    9369        $dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), basename( $dst_file ) ); 
    9470 
    95         if ( 'image/png' == $image_type && imagepng( $dst, $dst_file ) ) 
    96                 return $dst_file; 
    97         elseif ( imagejpeg( $dst, $dst_file, apply_filters( 'jpeg_quality', 90, 'wp_crop_image' ) ) ) 
    98                 return $dst_file; 
    99         else 
    100                 return false; 
     71        $result = $editor->save( $dst_file ); 
     72        return $result['file']; 
    10173} 
    10274 
    10375/** 
    function wp_generate_attachment_metadata( $attachment_id, $file ) { 
    144116 
    145117                $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes ); 
    146118 
    147                 foreach ($sizes as $size => $size_data ) { 
    148                         $resized = image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'] ); 
    149                         if ( $resized ) 
    150                                 $metadata['sizes'][$size] = $resized; 
    151                 } 
     119                $editor = WP_Image_Editor::get_instance( $file ); 
     120                $metadata['sizes'] = $editor->multi_resize( $sizes ); 
     121                unset( $editor ); 
    152122 
    153123                // fetch additional metadata from exif/iptc 
    154124                $image_meta = wp_read_image_metadata( $file ); 
  • new file wp-includes/class-wp-image-editor.php

    diff --git wp-includes/class-wp-image-editor.php wp-includes/class-wp-image-editor.php
    new file mode 100644
    index 0000000..cf34389
    - +  
     1<?php 
     2 
     3class WP_Image_Editor { 
     4 
     5        final public static function get_instance( $path ) { 
     6                $implementation = apply_filters( 'image_editor_class', self::choose_implementation(), $path ); 
     7 
     8                if ( $implementation ) 
     9                        return new $implementation( $path ); 
     10 
     11                return false; 
     12        } 
     13 
     14        /** 
     15         * Tests which editors are capable of supporting the request. 
     16         * 
     17         * @since 3.5.0 
     18         * @access private 
     19         * 
     20         * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request. 
     21         */ 
     22        private static function choose_implementation() { 
     23                static $implementation; 
     24 
     25                if ( null === $implementation ) { 
     26                        $request_order = apply_filters( 'wp_editors', array( 'gd' ) ); //'imagick', 
     27 
     28                        // Loop over each editor on each request looking for one which will serve this request's needs 
     29                        foreach ( $request_order as $editor ) { 
     30                                $class = 'WP_Image_Editor_' . $editor; 
     31 
     32                                // Check to see if this editor is a possibility, calls the editor statically 
     33                                if ( ! call_user_func( array( $class, 'test' ) ) ) 
     34                                        continue; 
     35 
     36                                if( ! apply_filters( 'wp_editor_use_' . $editor, true ) ) 
     37                                        continue; 
     38 
     39                                $implementation = $class; 
     40                        } 
     41                } 
     42 
     43                return $implementation; 
     44        } 
     45} 
     46 No newline at end of file 
  • wp-includes/deprecated.php

    diff --git wp-includes/deprecated.php wp-includes/deprecated.php
    index 8718586..ca1af12 100644
    function _get_post_ancestors( &$post ) { 
    32063206} 
    32073207 
    32083208/** 
     3209 * Load an image from a string, if PHP supports it. 
     3210 * 
     3211 * @since 2.1.0 
     3212 * @deprecated 3.5.0 
     3213 * @deprecated wp_get_image_for_editing() 
     3214 * 
     3215 * @param string $file Filename of the image to load. 
     3216 * @return resource The resulting image resource on success, Error string on failure. 
     3217 */ 
     3218function wp_load_image( $file ) { 
     3219        _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' ); 
     3220 
     3221        if ( is_numeric( $file ) ) 
     3222                $file = get_attached_file( $file ); 
     3223 
     3224        if ( ! file_exists( $file ) ) 
     3225                return sprintf(__('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file); 
     3226 
     3227        if ( ! function_exists('imagecreatefromstring') ) 
     3228                return __('The GD image library is not installed.'); 
     3229 
     3230        // Set artificially high because GD uses uncompressed images in memory 
     3231        @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 
     3232        $image = imagecreatefromstring( file_get_contents( $file ) ); 
     3233 
     3234        if ( !is_resource( $image ) ) 
     3235                return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file); 
     3236 
     3237        return $image; 
     3238} 
     3239 
     3240/** 
     3241 * Scale down an image to fit a particular size and save a new copy of the image. 
     3242 * 
     3243 * The PNG transparency will be preserved using the function, as well as the 
     3244 * image type. If the file going in is PNG, then the resized image is going to 
     3245 * be PNG. The only supported image types are PNG, GIF, and JPEG. 
     3246 * 
     3247 * Some functionality requires API to exist, so some PHP version may lose out 
     3248 * support. This is not the fault of WordPress (where functionality is 
     3249 * downgraded, not actual defects), but of your PHP version. 
     3250 * 
     3251 * @since 2.5.0 
     3252 * @deprecated 3.5.0 
     3253 * @deprecated wp_get_image_for_editing() 
     3254 * 
     3255 * @param string $file Image file path. 
     3256 * @param int $max_w Maximum width to resize to. 
     3257 * @param int $max_h Maximum height to resize to. 
     3258 * @param bool $crop Optional. Whether to crop image or resize. 
     3259 * @param string $suffix Optional. File suffix. 
     3260 * @param string $dest_path Optional. New image file path. 
     3261 * @param int $jpeg_quality Optional, default is 90. Image quality percentage. 
     3262 * @return mixed WP_Error on failure. String with new destination path. 
     3263 */ 
     3264function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { 
     3265        _deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' ); 
     3266 
     3267        $editor = new WP_Image_Editor_GD( $file ); 
     3268        $editor->set_quality( $jpeg_quality ); 
     3269 
     3270        $editor->resize( $max_w, $max_h, $crop ); 
     3271        $editor->save( $editor->generate_filename( $suffix, $dest_path ) ); 
     3272        unset( $editor ); 
     3273} 
     3274 
     3275/** 
    32093276 * Retrieve a single post, based on post ID. 
    32103277 * 
    32113278 * Has categories in 'post_category' property or key. Has tags in 'tags_input' 
  • new file wp-includes/editors/class-wp-image-editor-base.php

    diff --git wp-includes/editors/class-wp-image-editor-base.php wp-includes/editors/class-wp-image-editor-base.php
    new file mode 100644
    index 0000000..ff85ba0
    - +  
     1<?php 
     2 
     3class WP_Image_Editor_Base { 
     4        protected $file = false; 
     5        protected $size = false; 
     6        protected $orig_type  = false; 
     7        protected $quality = 90; 
     8 
     9        function __construct( $filename ) { 
     10                $this->file = $filename; 
     11        } 
     12 
     13        public static function test() { 
     14                return false; 
     15        } 
     16 
     17        public function get_size() { 
     18                return $this->size; 
     19        } 
     20 
     21        protected function update_size( $width = false, $height = false ) { 
     22                $this->size = array( 
     23                        'width' => $width, 
     24                        'height' => $height 
     25                ); 
     26        } 
     27 
     28        public function set_quality( $quality ) { 
     29                $this->quality = apply_filters( 'wp_editor_set_quality', $quality ); 
     30        } 
     31 
     32        public function generate_filename( $suffix = null, $dest_path = null ) { 
     33                // $suffix will be appended to the destination filename, just before the extension 
     34                $suffix = $this->get_suffix(); 
     35 
     36                $info = pathinfo( $this->file ); 
     37                $dir  = $info['dirname']; 
     38                $ext  = $info['extension']; 
     39                $name = wp_basename( $this->file, ".$ext" ); 
     40 
     41                if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) ) 
     42                        $dir = $_dest_path; 
     43 
     44                return "{$dir}/{$name}-{$suffix}.{$ext}"; 
     45        } 
     46 
     47        public function get_suffix() { 
     48                if ( ! $this->get_size() ) 
     49                        return; 
     50 
     51                return "{$this->size['width']}x{$this->size['height']}"; 
     52        } 
     53} 
     54 No newline at end of file 
  • new file wp-includes/editors/class-wp-image-editor-gd.php

    diff --git wp-includes/editors/class-wp-image-editor-gd.php wp-includes/editors/class-wp-image-editor-gd.php
    new file mode 100644
    index 0000000..dcb5f3f
    - +  
     1<?php 
     2 
     3class WP_Image_Editor_GD extends WP_Image_Editor_Base { 
     4        private $image = false; // GD Resource 
     5 
     6        function __destruct() { 
     7                if ( $this->image ) { 
     8                        // we don't need the original in memory anymore 
     9                        imagedestroy( $this->image ); 
     10                } 
     11        } 
     12 
     13        /** 
     14         * Checks to see if GD is available. 
     15         * 
     16         * @return boolean 
     17         */ 
     18        public static function test() { 
     19                if ( ! extension_loaded('gd') || ! function_exists('gd_info') ) 
     20                        return false; 
     21 
     22                return true; 
     23        } 
     24 
     25        /** 
     26         * Loads image from $this->file into GD Resource 
     27         * 
     28         * @since 3.5 
     29         * 
     30         * @return boolean|\WP_Error 
     31         */ 
     32        private function load() { 
     33                if ( $this->image ) 
     34                        return true; 
     35 
     36                if ( ! file_exists( $this->file ) ) 
     37                        return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $this->file ); 
     38 
     39                if ( ! function_exists('imagecreatefromstring') ) 
     40                        return __('The GD image library is not installed.'); 
     41 
     42                // Set artificially high because GD uses uncompressed images in memory 
     43                @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 
     44                $this->image = imagecreatefromstring( file_get_contents( $this->file ) ); 
     45 
     46                if ( ! is_resource( $this->image ) ) 
     47                        return sprintf( __('File &#8220;%s&#8221; is not an image.'), $this->file ); 
     48 
     49                $size = @getimagesize( $this->file ); 
     50                if ( ! $size ) 
     51                        return new WP_Error( 'invalid_image', __('Could not read image size'), $this->file ); 
     52 
     53                $this->update_size( $size[0], $size[1] ); 
     54                $this->orig_type = $size['mime']; 
     55 
     56                return true; 
     57        } 
     58 
     59        public function get_size() { 
     60                if ( ! $this->load() ) 
     61                        return; 
     62 
     63                return parent::get_size(); 
     64        } 
     65 
     66        protected function update_size( $width = false, $height = false ) { 
     67                if ( ! $this->load() ) 
     68                        return; 
     69 
     70                parent::update_size( $width ?: imagesx( $this->image ), $height ?: imagesy( $this->image ) ); 
     71        } 
     72 
     73        public function resize( $max_w, $max_h, $crop = false ) { 
     74                $resized = $this->_resize( $max_w, $max_h, $crop ); 
     75 
     76                if ( is_resource( $resized ) ) { 
     77                        imagedestroy( $this->image ); 
     78                        $this->image = $resized; 
     79 
     80                        return true; 
     81                } 
     82 
     83                return $resized; 
     84        } 
     85 
     86        protected function _resize( $max_w, $max_h, $crop ) { 
     87                if ( ! $this->load() ) 
     88                        return; 
     89 
     90                $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); 
     91                if ( ! $dims ) { 
     92                        return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') ); 
     93                } 
     94                list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; 
     95 
     96                $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); 
     97                imagecopyresampled( $resized, $this->image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); 
     98 
     99                if ( is_resource( $resized ) ) { 
     100                        $this->update_size( $dst_w, $dst_h ); 
     101                        return $resized; 
     102                } 
     103 
     104                return false; 
     105        } 
     106 
     107        /** 
     108         * Processes current image and saves to disk 
     109         * multiple sizes from single source. 
     110         * 
     111         * @param array $sizes 
     112         * @return array 
     113         */ 
     114        public function multi_resize( $sizes ) { 
     115                $metadata = array(); 
     116                if ( ! $this->load() ) 
     117                        return $metadata; 
     118 
     119                $orig_size = $this->size; 
     120                foreach ( $sizes as $size => $size_data ) { 
     121                        $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); 
     122 
     123                        if( ! is_wp_error( $image ) ) { 
     124                                $resized = $this->_save( $image ); 
     125 
     126                                imagedestroy( $image ); 
     127                                unset( $resized['path'] ); 
     128 
     129                                if ( ! is_wp_error( $resized ) && $resized ) 
     130                                        $metadata[$size] = $resized; 
     131                        } 
     132 
     133                        $this->size = $orig_size; 
     134                } 
     135 
     136                return $metadata; 
     137        } 
     138 
     139        /** 
     140         * Ported from image.php 
     141         * 
     142         * @param float $x 
     143         * @param float $y 
     144         * @param float $w 
     145         * @param float $h 
     146         * @return boolean 
     147         */ 
     148        public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false ) { 
     149                if ( ! $this->load() ) 
     150                        return; 
     151 
     152                // If destination width/height isn't specified, use same as 
     153                // width/height from source. 
     154                $dst_w = $dst_w ?: $src_w; 
     155                $dst_h = $dst_h ?: $src_h; 
     156                $dst = wp_imagecreatetruecolor( $dst_w, $dst_h ); 
     157 
     158                if ( $src_abs ) { 
     159                        $src_w -= $src_x; 
     160                        $src_h -= $src_y; 
     161                } 
     162 
     163                if ( function_exists( 'imageantialias' ) ) 
     164                        imageantialias( $dst, true ); 
     165 
     166                imagecopyresampled( $dst, $this->image, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ); 
     167 
     168                if ( is_resource( $dst ) ) { 
     169                        imagedestroy( $this->image ); 
     170                        $this->image = $dst; 
     171                        $this->update_size( $dst_w, $dst_h ); 
     172                        return true; 
     173                } 
     174 
     175                return false; // @TODO: WP_Error here. 
     176        } 
     177 
     178        /** 
     179         * Rotates in memory image by $angle. 
     180         * Ported from image-edit.php 
     181         * 
     182         * @param float $angle 
     183         * @return boolean 
     184         */ 
     185        public function rotate( $angle ) { 
     186                if ( ! $this->load() ) 
     187                        return; 
     188 
     189                if ( function_exists('imagerotate') ) { 
     190                        $rotated = imagerotate( $this->image, $angle, 0 ); 
     191 
     192                        if ( is_resource( $rotated ) ) { 
     193                                imagedestroy( $this->image ); 
     194                                $this->image = $rotated; 
     195                                $this->update_size(); 
     196                                return true; 
     197                        } 
     198                } 
     199                return false; // @TODO: WP_Error here. 
     200        } 
     201 
     202        /** 
     203         * Ported from image-edit.php 
     204         * 
     205         * @param boolean $horz 
     206         * @param boolean $vert 
     207         */ 
     208        public function flip( $horz, $vert ) { 
     209                if ( ! $this->load() ) 
     210                        return; 
     211 
     212                $w = $this->size['width']; 
     213                $h = $this->size['height']; 
     214                $dst = wp_imagecreatetruecolor( $w, $h ); 
     215 
     216                if ( is_resource( $dst ) ) { 
     217                        $sx = $vert ? ($w - 1) : 0; 
     218                        $sy = $horz ? ($h - 1) : 0; 
     219                        $sw = $vert ? -$w : $w; 
     220                        $sh = $horz ? -$h : $h; 
     221 
     222                        if ( imagecopyresampled( $dst, $this->image, 0, 0, $sx, $sy, $w, $h, $sw, $sh ) ) { 
     223                                imagedestroy( $this->image ); 
     224                                $this->image = $dst; 
     225                                return true; 
     226                        } 
     227                } 
     228 
     229                return false; // @TODO: WP_Error here. 
     230        } 
     231 
     232        /** 
     233         * Saves current in-memory image to file 
     234         * 
     235         * @param string $destfilename 
     236         * @return array 
     237         */ 
     238        public function save( $destfilename = null ) { 
     239                $saved = $this->_save( $this->image, $destfilename ); 
     240 
     241                if ( ! is_wp_error( $saved ) && $destfilename ) 
     242                        $this->file = $destfilename; 
     243 
     244                return $saved; 
     245        } 
     246 
     247        protected function _save( $image, $destfilename = null ) { 
     248                if ( ! $this->load() ) 
     249                        return; 
     250 
     251                if ( null == $destfilename ) { 
     252                        $destfilename = $this->generate_filename(); 
     253                } 
     254 
     255                if ( 'image/gif' == $this->orig_type ) { 
     256                        if ( ! $this->make_image( 'imagegif', $image, $destfilename ) ) 
     257                                return new WP_Error( 'image_editor_save_failed', __( 'Image Editor Save Failed' ) ); 
     258                } 
     259                elseif ( 'image/png' == $this->orig_type ) { 
     260                        // convert from full colors to index colors, like original PNG. 
     261                        if ( function_exists('imageistruecolor') && ! imageistruecolor( $image ) ) 
     262                                imagetruecolortopalette( $image, false, imagecolorstotal( $image ) ); 
     263 
     264                        if ( ! $this->make_image( 'imagepng', $image, $destfilename ) ) 
     265                                return new WP_Error( 'image_editor_save_failed', __( 'Image Editor Save Failed' ) ); 
     266                } 
     267                else { 
     268                        if ( ! $this->make_image( 'imagejpeg', $image, $destfilename, apply_filters( 'jpeg_quality', $this->quality, 'image_resize' ) ) ) 
     269                                return new WP_Error( 'image_editor_save_failed', __( 'Image Editor Save Failed' ) ); 
     270                } 
     271 
     272                // Set correct file permissions 
     273                $stat = stat( dirname( $destfilename ) ); 
     274                $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits 
     275                @ chmod( $destfilename, $perms ); 
     276 
     277                return array( 
     278                        'path' => $destfilename, 
     279                        'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $destfilename ) ), 
     280                        'width' => $this->size['width'], 
     281                        'height' => $this->size['height'] 
     282                ); 
     283        } 
     284 
     285        /** 
     286         * Returns stream of current image 
     287         */ 
     288        public function stream() { 
     289                if ( ! $this->load() ) 
     290                        return; 
     291 
     292                switch ( $this->orig_type ) { 
     293                        case 'image/jpeg': 
     294                                header( 'Content-Type: image/jpeg' ); 
     295                                return imagejpeg( $this->image, null, $this->quality ); 
     296                        case 'image/png': 
     297                                header( 'Content-Type: image/png' ); 
     298                                return imagepng( $this->image ); 
     299                        case 'image/gif': 
     300                                header( 'Content-Type: image/gif' ); 
     301                                return imagegif( $this->image ); 
     302                        default: 
     303                                return false; 
     304                } 
     305        } 
     306 
     307        public function generate_filename( $suffix = null, $dest_path = null ) { 
     308                if ( ! $this->load() ) 
     309                        return; 
     310 
     311                return parent::generate_filename( $suffix, $dest_path ); 
     312        } 
     313 
     314        public function get_suffix() { 
     315                if ( ! $this->load() ) 
     316                        return; 
     317 
     318                return parent::get_suffix(); 
     319        } 
     320 
     321        private function make_image( $function, $image, $filename, $quality = -1, $filters = null ) { 
     322                $dst_file = $filename; 
     323 
     324                if ( $stream = wp_is_stream( $filename ) ) { 
     325                        $filename = null; 
     326                        ob_start(); 
     327                } 
     328 
     329                $result = call_user_func( $function, $image, $filename, $quality, $filters ); 
     330 
     331                if( $result && $stream ) { 
     332                        $contents = ob_get_contents(); 
     333 
     334                        $fp = fopen( $dst_file, 'w' ); 
     335 
     336                        if( ! $fp ) 
     337                                return false; 
     338 
     339                        fwrite( $fp, $contents ); 
     340                        fclose( $fp ); 
     341                } 
     342 
     343                if( $stream ) { 
     344                        ob_end_clean(); 
     345                } 
     346 
     347                return $result; 
     348        } 
     349} 
     350 No newline at end of file 
  • new file wp-includes/editors/class-wp-image-editor-imagick.php

    diff --git wp-includes/editors/class-wp-image-editor-imagick.php wp-includes/editors/class-wp-image-editor-imagick.php
    new file mode 100644
    index 0000000..d01fe10
    - +  
     1<?php 
     2 
     3class WP_Image_Editor_Imagick extends WP_Image_Editor_Base { 
     4        private $image = false; // Imagick Object 
     5 
     6        public static function test() { 
     7                if ( ! extension_loaded('imagick') ) 
     8                        return false; 
     9 
     10                return true; 
     11        } 
     12 
     13        private function load() { 
     14                if ( ! file_exists( $this->file ) ) 
     15                        return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $this->file ); 
     16 
     17                try { 
     18                        $this->image = new Imagick( $this->file ); 
     19                } 
     20                catch ( Exception $e ) { 
     21                        return sprintf(__('File &#8220;%s&#8221; is not an image.'), $this->file); 
     22                } 
     23 
     24                if( ! $this->image->valid() ) { 
     25                        return sprintf(__('File &#8220;%s&#8221; is not an image.'), $this->file); 
     26                } 
     27 
     28                $this->update_size(); 
     29                $this->orig_type  = $this->image->getImageFormat(); 
     30                if ( ! $this->size ) 
     31                        return new WP_Error( 'invalid_image', __('Could not read image size'), $this->file ); 
     32 
     33                return true; 
     34        } 
     35 
     36        protected function update_size( $width = false, $height = false ) { 
     37                if ( ! $this->load() ) 
     38                        return false; 
     39 
     40                $size = null; 
     41                if ( !$this->size || $width || $height ) { 
     42                        try { 
     43                                $size = $this->image->getImageFormat(); 
     44                        } 
     45                        catch ( Exception $e ) { 
     46                                return sprintf(__('File &#8220;%s&#8221; couldn\'t be checked for size.'), $this->file); 
     47                        } 
     48                } 
     49 
     50                parent::update_size( $width ?: $size['height'], $height ?: $size['width'] ); 
     51        } 
     52 
     53        public function resize( $max_w, $max_h, $crop = false ) { 
     54                // Yes, this is forcing a load every time at the moment. 
     55                // However, for multi-resize to work, it needs to do so, unless it's going to resize based on a modified image. 
     56                if ( ! $this->load() ) 
     57                        return false; 
     58 
     59                if ( ! is_object( $this->image ) ) 
     60                        return new WP_Error( 'error_loading_image', $this->image, $this->file ); 
     61 
     62                $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); 
     63                if ( ! $dims ) 
     64                        return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') ); 
     65                list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; 
     66 
     67                if( 'JPEG' == $this->orig_type ) { 
     68                        $this->image->setImageCompressionQuality( apply_filters( 'jpeg_quality', $this->quality, 'image_resize' ) ); 
     69                        $this->image->setImageCompression( imagick::COMPRESSION_JPEG ); 
     70                } 
     71                else { 
     72                        $this->image->setImageCompressionQuality( $this->quality ); 
     73                } 
     74 
     75                if ( $crop ) { 
     76                        $this->image->cropImage( $src_w, $src_h, $src_x, $src_y ); 
     77                } 
     78 
     79                //$this->image->thumbnailImage( $dst_w, $dst_h ); 
     80                $this->image->scaleImage( $dst_w, $dst_h, true ); 
     81        } 
     82 
     83        /** 
     84         * Saves current image to file 
     85         * 
     86         * @param string $destfilename 
     87         * @return array 
     88         */ 
     89        public function save( $destfilename = null ) { 
     90                $saved = $this->_save( $this->image, $destfilename ); 
     91 
     92                if ( ! is_wp_error( $saved ) && $destfilename ) 
     93                        $this->file = $destfilename; 
     94 
     95                return $saved; 
     96        } 
     97 
     98        protected function _save( $image, $destfilename = null ) { 
     99                if ( ! $this->load() ) 
     100                        return; 
     101 
     102                if ( null == $destfilename ) { 
     103                        $destfilename = $this->generate_filename(); 
     104                } 
     105 
     106                if( apply_filters( 'wp_editors_stripimage', true ) ) { 
     107                        $this->image->stripImage(); 
     108                } 
     109 
     110                $this->image->writeImage( $destfilename ); 
     111 
     112                // Set correct file permissions 
     113                $stat = stat( dirname( $destfilename ) ); 
     114                $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits 
     115                @ chmod( $destfilename, $perms ); 
     116 
     117                return array( 
     118                        'path' => $destfilename, 
     119                        'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $destfilename ) ), 
     120                        'width' => $this->size['width'], 
     121                        'height' => $this->size['height'] 
     122                ); 
     123        } 
     124 
     125        public function generate_filename( $suffix = null, $dest_path = null ) { 
     126                if ( ! $this->load() ) 
     127                        return; 
     128 
     129                return parent::generate_filename( $suffix, $dest_path ); 
     130        } 
     131 
     132        public function get_suffix() { 
     133                if ( ! $this->load() ) 
     134                        return; 
     135 
     136                return parent::get_suffix(); 
     137        } 
     138} 
     139 No newline at end of file 
  • wp-includes/functions.php

    diff --git wp-includes/functions.php wp-includes/functions.php
    index 91314b5..7d4657c 100644
    function wp_get_original_referer() { 
    12921292 * @return bool Whether the path was created. True if path already exists. 
    12931293 */ 
    12941294function wp_mkdir_p( $target ) { 
     1295        $wrapper = null; 
     1296 
     1297        // strip the protocol 
     1298        if( wp_is_stream( $target ) ) { 
     1299                list( $wrapper, $target ) = explode( '://', $target, 2 ); 
     1300        } 
     1301 
    12951302        // from php.net/mkdir user contributed notes 
    12961303        $target = str_replace( '//', '/', $target ); 
    12971304 
     1305        // put the wrapper back on the target 
     1306        if( $wrapper !== null ) { 
     1307                $target = $wrapper . '://' . $target; 
     1308        } 
     1309 
    12981310        // safe mode fails with a trailing slash under certain PHP versions. 
    12991311        $target = rtrim($target, '/'); // Use rtrim() instead of untrailingslashit to avoid formatting.php dependency. 
    13001312        if ( empty($target) ) 
    function _device_can_upload() { 
    36843696        return true; 
    36853697} 
    36863698 
     3699/** 
     3700 * Test if a given path is a stream URL 
     3701 *  
     3702 * @param string $path The resource path or URL 
     3703 * @return bool True if the path is a stream URL 
     3704 */ 
     3705function wp_is_stream( $path ) { 
     3706        $wrappers = stream_get_wrappers(); 
     3707        $wrappers_re = '(' . join('|', $wrappers) . ')'; 
     3708 
     3709        return preg_match( "!^$wrappers_re://!", $path ) === 1; 
     3710} 
  • wp-includes/media.php

    diff --git wp-includes/media.php wp-includes/media.php
    index 342edd4..56e0a1a 100644
    function get_image_tag($id, $alt, $title, $align, $size='medium') { 
    236236} 
    237237 
    238238/** 
    239  * Load an image from a string, if PHP supports it. 
    240  * 
    241  * @since 2.1.0 
    242  * 
    243  * @param string $file Filename of the image to load. 
    244  * @return resource The resulting image resource on success, Error string on failure. 
    245  */ 
    246 function wp_load_image( $file ) { 
    247         if ( is_numeric( $file ) ) 
    248                 $file = get_attached_file( $file ); 
    249  
    250         if ( ! file_exists( $file ) ) 
    251                 return sprintf(__('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file); 
    252  
    253         if ( ! function_exists('imagecreatefromstring') ) 
    254                 return __('The GD image library is not installed.'); 
    255  
    256         // Set artificially high because GD uses uncompressed images in memory 
    257         @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 
    258         $image = imagecreatefromstring( file_get_contents( $file ) ); 
    259  
    260         if ( !is_resource( $image ) ) 
    261                 return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file); 
    262  
    263         return $image; 
    264 } 
    265  
    266 /** 
    267239 * Calculates the new dimensions for a downsampled image. 
    268240 * 
    269241 * If either width or height are empty, no constraint is applied on 
    function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = fal 
    393365} 
    394366 
    395367/** 
    396  * Scale down an image to fit a particular size and save a new copy of the image. 
    397  * 
    398  * The PNG transparency will be preserved using the function, as well as the 
    399  * image type. If the file going in is PNG, then the resized image is going to 
    400  * be PNG. The only supported image types are PNG, GIF, and JPEG. 
    401  * 
    402  * Some functionality requires API to exist, so some PHP version may lose out 
    403  * support. This is not the fault of WordPress (where functionality is 
    404  * downgraded, not actual defects), but of your PHP version. 
    405  * 
    406  * @since 2.5.0 
    407  * 
    408  * @param string $file Image file path. 
    409  * @param int $max_w Maximum width to resize to. 
    410  * @param int $max_h Maximum height to resize to. 
    411  * @param bool $crop Optional. Whether to crop image or resize. 
    412  * @param string $suffix Optional. File suffix. 
    413  * @param string $dest_path Optional. New image file path. 
    414  * @param int $jpeg_quality Optional, default is 90. Image quality percentage. 
    415  * @return mixed WP_Error on failure. String with new destination path. 
    416  */ 
    417 function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { 
    418  
    419         $image = wp_load_image( $file ); 
    420         if ( !is_resource( $image ) ) 
    421                 return new WP_Error( 'error_loading_image', $image, $file ); 
    422  
    423         $size = @getimagesize( $file ); 
    424         if ( !$size ) 
    425                 return new WP_Error('invalid_image', __('Could not read image size'), $file); 
    426         list($orig_w, $orig_h, $orig_type) = $size; 
    427  
    428         $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop); 
    429         if ( !$dims ) 
    430                 return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') ); 
    431         list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims; 
    432  
    433         $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h ); 
    434  
    435         imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); 
    436  
    437         // convert from full colors to index colors, like original PNG. 
    438         if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) ) 
    439                 imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) ); 
    440  
    441         // we don't need the original in memory anymore 
    442         imagedestroy( $image ); 
    443  
    444         // $suffix will be appended to the destination filename, just before the extension 
    445         if ( !$suffix ) 
    446                 $suffix = "{$dst_w}x{$dst_h}"; 
    447  
    448         $info = pathinfo($file); 
    449         $dir = $info['dirname']; 
    450         $ext = $info['extension']; 
    451         $name = wp_basename($file, ".$ext"); 
    452  
    453         if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) ) 
    454                 $dir = $_dest_path; 
    455         $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; 
    456  
    457         if ( IMAGETYPE_GIF == $orig_type ) { 
    458                 if ( !imagegif( $newimage, $destfilename ) ) 
    459                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); 
    460         } elseif ( IMAGETYPE_PNG == $orig_type ) { 
    461                 if ( !imagepng( $newimage, $destfilename ) ) 
    462                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); 
    463         } else { 
    464                 // all other formats are converted to jpg 
    465                 if ( 'jpg' != $ext && 'jpeg' != $ext ) 
    466                         $destfilename = "{$dir}/{$name}-{$suffix}.jpg"; 
    467                 if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) ) 
    468                         return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); 
    469         } 
    470  
    471         imagedestroy( $newimage ); 
    472  
    473         // Set correct file permissions 
    474         $stat = stat( dirname( $destfilename )); 
    475         $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits 
    476         @ chmod( $destfilename, $perms ); 
    477  
    478         return $destfilename; 
    479 } 
    480  
    481 /** 
    482368 * Resize an image to make a thumbnail or intermediate size. 
    483369 * 
    484370 * The returned array has the file size, the image width, and image height. The 
    function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $de 
    493379 * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize. 
    494380 * @return bool|array False, if no image was created. Metadata array on success. 
    495381 */ 
    496 function image_make_intermediate_size($file, $width, $height, $crop=false) { 
     382function image_make_intermediate_size( $file, $width, $height, $crop = false ) { 
    497383        if ( $width || $height ) { 
    498                 $resized_file = image_resize($file, $width, $height, $crop); 
    499                 if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) { 
    500                         $resized_file = apply_filters('image_make_intermediate_size', $resized_file); 
    501                         return array( 
    502                                 'file' => wp_basename( $resized_file ), 
    503                                 'width' => $info[0], 
    504                                 'height' => $info[1], 
    505                         ); 
     384                $editor = WP_Image_Editor::get_instance( $file ); 
     385                $editor->resize( $width, $height, $crop ); 
     386                $resized_file = $editor->save(); 
     387 
     388                unset( $editor ); 
     389 
     390                if ( ! is_wp_error( $resized_file ) && $resized_file ) { 
     391                        unset( $resized_file['path'] ); 
     392                        return $resized_file; 
    506393                } 
    507394        } 
    508395        return false; 
  • wp-settings.php

    diff --git wp-settings.php wp-settings.php
    index 2db338b..80fd5d5 100644
    require( ABSPATH . WPINC . '/nav-menu.php' ); 
    142142require( ABSPATH . WPINC . '/nav-menu-template.php' ); 
    143143require( ABSPATH . WPINC . '/admin-bar.php' ); 
    144144 
     145require( ABSPATH . WPINC . '/class-wp-image-editor.php' ); 
     146require( ABSPATH . WPINC . '/editors/class-wp-image-editor-base.php' ); 
     147require( ABSPATH . WPINC . '/editors/class-wp-image-editor-gd.php' ); 
     148require( ABSPATH . WPINC . '/editors/class-wp-image-editor-imagick.php' ); 
     149 
    145150// Load multisite-specific files. 
    146151if ( is_multisite() ) { 
    147152        require( ABSPATH . WPINC . '/ms-functions.php' );