WordPress.org

Make WordPress Core

Ticket #35725: 35725.diff

File 35725.diff, 28.1 KB (added by blobfolio, 3 years ago)

Patch with upload_mimes and image editor integration.

  • src/wp-admin/custom-header.php

    diff --git src/wp-admin/custom-header.php src/wp-admin/custom-header.php
    index c1a7896589..e7664a51f9 100644
    wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); 
    777777                }
    778778
    779779                if ( file_exists( $file ) ) {
    780                         list( $width, $height, $type, $attr ) = getimagesize( $file );
     780                        list( $width, $height, $type, $attr ) = wp_get_image_size( $file );
    781781                } else {
    782782                        $data   = wp_get_attachment_metadata( $attachment_id );
    783783                        $height = isset( $data['height'] ) ? $data['height'] : 0;
    wp_nonce_field( 'custom-header-options', '_wpnonce-custom-header-options' ); 
    12091209                $parent_url = wp_get_attachment_url( $parent->ID );
    12101210                $url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
    12111211
    1212                 $size       = @getimagesize( $cropped );
     1212                $size       = wp_get_image_size( $cropped );
    12131213                $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
    12141214
    12151215                $object = array(
  • src/wp-admin/includes/ajax-actions.php

    diff --git src/wp-admin/includes/ajax-actions.php src/wp-admin/includes/ajax-actions.php
    index 8ced5d335a..9121fdc2f5 100644
    function wp_ajax_crop_image() { 
    36113611                        $parent_url = wp_get_attachment_url( $attachment_id );
    36123612                        $url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
    36133613
    3614                         $size       = @getimagesize( $cropped );
     3614                        $size       = wp_get_image_size( $cropped );
    36153615                        $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
    36163616
    36173617                        $object = array(
  • src/wp-admin/includes/class-wp-site-icon.php

    diff --git src/wp-admin/includes/class-wp-site-icon.php src/wp-admin/includes/class-wp-site-icon.php
    index 47c48572f3..74d32df2b4 100644
    class WP_Site_Icon { 
    8787                $parent_url = wp_get_attachment_url( $parent->ID );
    8888                $url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
    8989
    90                 $size       = @getimagesize( $cropped );
     90                $size       = wp_get_image_size( $cropped );
    9191                $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
    9292
    9393                $object = array(
  • src/wp-admin/includes/image-edit.php

    diff --git src/wp-admin/includes/image-edit.php src/wp-admin/includes/image-edit.php
    index 2f474d4caa..3f4132a9a5 100644
    function wp_stream_image( $image, $mime_type, $attachment_id ) { 
    294294                        case 'image/gif':
    295295                                header( 'Content-Type: image/gif' );
    296296                                return imagegif( $image );
     297                        case 'image/webp':
     298                                if ( function_exists( 'imagewebp' ) ) {
     299                                        header( 'Content-Type: image/webp' );
     300                                        return imagewebp( $image, null, 90 );
     301                                }
     302                                return false;
    297303                        default:
    298304                                return false;
    299305                }
    function wp_save_image_file( $filename, $image, $mime_type, $post_id ) { 
    371377                                return imagepng( $image, $filename );
    372378                        case 'image/gif':
    373379                                return imagegif( $image, $filename );
     380                        case 'image/webp':
     381                                if ( function_exists( 'imagewebp' ) ) {
     382                                        return imagewebp( $image, null, apply_filters( 'jpeg_quality', 90, 'edit_image' ) );
     383                                }
     384                                return false;
    374385                        default:
    375386                                return false;
    376387                }
  • src/wp-admin/includes/image.php

    diff --git src/wp-admin/includes/image.php src/wp-admin/includes/image.php
    index 3fe8cc8e69..5bf56aa54b 100644
    function wp_generate_attachment_metadata( $attachment_id, $file ) { 
    8383        $mime_type = get_post_mime_type( $attachment );
    8484
    8585        if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
    86                 $imagesize          = getimagesize( $file );
     86                $imagesize          = wp_get_image_size( $file );
    8787                $metadata['width']  = $imagesize[0];
    8888                $metadata['height'] = $imagesize[1];
    8989
    function wp_generate_attachment_metadata( $attachment_id, $file ) { 
    186186                                case 'image/png':
    187187                                        $ext = '.png';
    188188                                        break;
     189                                case 'image/webp':
     190                                        $ext = '.webp';
     191                                        break;
    189192                        }
    190193                        $basename = str_replace( '.', '-', basename( $file ) ) . '-image' . $ext;
    191194                        $uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
    function wp_read_image_metadata( $file ) { 
    355358                return false;
    356359        }
    357360
    358         list( , , $sourceImageType ) = getimagesize( $file );
     361        list( , , $sourceImageType ) = wp_get_image_size( $file );
    359362
    360363        /*
    361364         * EXIF contains a bunch of data we'll probably never need formatted in ways
    function wp_read_image_metadata( $file ) { 
    384387         * as caption, description etc.
    385388         */
    386389        if ( is_callable( 'iptcparse' ) ) {
    387                 getimagesize( $file, $info );
     390                wp_get_image_size( $file, $info );
    388391
    389392                if ( ! empty( $info['APP13'] ) ) {
    390393                        $iptc = iptcparse( $info['APP13'] );
    function wp_read_image_metadata( $file ) { 
    539542 * @return bool True if valid image, false if not valid image.
    540543 */
    541544function file_is_valid_image( $path ) {
    542         $size = @getimagesize( $path );
     545        $size = wp_get_image_size( $path );
    543546        return ! empty( $size );
    544547}
    545548
    function file_is_valid_image( $path ) { 
    552555 * @return bool True if suitable, false if not suitable.
    553556 */
    554557function file_is_displayable_image( $path ) {
    555         $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP );
     558        $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_WEBP );
    556559
    557         $info = @getimagesize( $path );
     560        $info = wp_get_image_size( $path );
    558561        if ( empty( $info ) ) {
    559562                $result = false;
    560563        } elseif ( ! in_array( $info[2], $displayable_image_types ) ) {
    function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) { 
    600603                case 'image/gif':
    601604                        $image = imagecreatefromgif( $filepath );
    602605                        break;
     606                case 'image/webp':
     607                        if ( function_exists( 'imagecreatefromwebp' ) ) {
     608                                $image = imagecreatefromwebp( $filepath );
     609                        } else {
     610                                $image = false;
     611                        }
     612                        break;
    603613                default:
    604614                        $image = false;
    605615                        break;
  • src/wp-admin/includes/schema.php

    diff --git src/wp-admin/includes/schema.php src/wp-admin/includes/schema.php
    index edba6973a0..9cdf6ee4a4 100644
    We hope you enjoy your new site. Thanks! 
    10731073                'jpeg',
    10741074                'png',
    10751075                'gif',
     1076                'webp',
    10761077                // Video.
    10771078                'mov',
    10781079                'avi',
  • src/wp-includes/ID3/getid3.lib.php

    diff --git src/wp-includes/ID3/getid3.lib.php src/wp-includes/ID3/getid3.lib.php
    index 1931bb3724..e2dbd7e0b3 100644
    class getid3_lib 
    12011201                        if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) {
    12021202                                fwrite($tmp, $imgData);
    12031203                                fclose($tmp);
    1204                                 $GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
     1204                                $GetDataImageSize = wp_get_image_size($tempfilename, $imageinfo);
    12051205                                if (($GetDataImageSize === false) || !isset($GetDataImageSize[0]) || !isset($GetDataImageSize[1])) {
    12061206                                        return false;
    12071207                                }
    class getid3_lib 
    12351235                        $ImageTypesLookup[12] = 'jb2';
    12361236                        $ImageTypesLookup[13] = 'swc';
    12371237                        $ImageTypesLookup[14] = 'iff';
     1238                        $ImageTypesLookup[18] = 'webp';
    12381239                }
    12391240                return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : '');
    12401241        }
  • src/wp-includes/class-phpmailer.php

    diff --git src/wp-includes/class-phpmailer.php src/wp-includes/class-phpmailer.php
    index 7f5e353578..ed5b6cf10d 100644
    class PHPMailer 
    35873587            'png'   => 'image/png',
    35883588            'tiff'  => 'image/tiff',
    35893589            'tif'   => 'image/tiff',
     3590            'webp'  => 'image/webp',
    35903591            'eml'   => 'message/rfc822',
    35913592            'css'   => 'text/css',
    35923593            'html'  => 'text/html',
  • src/wp-includes/class-wp-image-editor-gd.php

    diff --git src/wp-includes/class-wp-image-editor-gd.php src/wp-includes/class-wp-image-editor-gd.php
    index c8d1ed2f8d..d027380b20 100644
    class WP_Image_Editor_GD extends WP_Image_Editor { 
    7373                                return ( $image_types & IMG_PNG ) != 0;
    7474                        case 'image/gif':
    7575                                return ( $image_types & IMG_GIF ) != 0;
     76                        case 'image/webp':
     77                                return ( $image_types & IMG_WEBP ) != 0;
    7678                }
    7779
    7880                return false;
    class WP_Image_Editor_GD extends WP_Image_Editor { 
    9799                // Set artificially high because GD uses uncompressed images in memory.
    98100                wp_raise_memory_limit( 'image' );
    99101
    100                 $this->image = @imagecreatefromstring( file_get_contents( $this->file ) );
     102                // WebP may not work with imagecreatefromstring().
     103                if (
     104                        function_exists( 'imagecreatefromwebp' ) &&
     105                        ( 'image/webp' === wp_get_image_mime( $this->file ) )
     106                ) {
     107                        $this->image = @imagecreatefromwebp( $this->file );
     108                }
     109                else {
     110                        $this->image = @imagecreatefromstring( file_get_contents( $this->file ) );
     111                }
    101112
    102113                if ( ! is_resource( $this->image ) ) {
    103114                        return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file );
    104115                }
    105116
    106                 $size = @getimagesize( $this->file );
     117                $size = wp_get_image_size( $this->file );
    107118                if ( ! $size ) {
    108119                        return new WP_Error( 'invalid_image', __( 'Could not read image size.' ), $this->file );
    109120                }
    class WP_Image_Editor_GD extends WP_Image_Editor { 
    412423                        if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) {
    413424                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    414425                        }
     426                } elseif ( 'image/webp' == $mime_type ) {
     427                        if ( ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) ) {
     428                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
     429                        }
    415430                } else {
    416431                        return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    417432                }
    class WP_Image_Editor_GD extends WP_Image_Editor { 
    455470                        case 'image/gif':
    456471                                header( 'Content-Type: image/gif' );
    457472                                return imagegif( $this->image );
     473                        case 'image/webp':
     474                                if ( function_exists( 'imagewebp' ) ) {
     475                                        header( 'Content-Type: image/webp' );
     476                                        return imagewebp( $this->image, null, $this->get_quality() );
     477                                }
    458478                        default:
    459479                                header( 'Content-Type: image/jpeg' );
    460480                                return imagejpeg( $this->image, null, $this->get_quality() );
  • src/wp-includes/class-wp-image-editor-imagick.php

    diff --git src/wp-includes/class-wp-image-editor-imagick.php src/wp-includes/class-wp-image-editor-imagick.php
    index 5db6fc4a86..cf75dbeeb1 100644
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    365365                        }
    366366
    367367                        // Set appropriate quality settings after resizing.
    368                         if ( 'image/jpeg' == $this->mime_type ) {
     368                        if ( 'image/jpeg' === $this->mime_type ) {
    369369                                if ( is_callable( array( $this->image, 'unsharpMaskImage' ) ) ) {
    370370                                        $this->image->unsharpMaskImage( 0.25, 0.25, 8, 0.065 );
    371371                                }
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    373373                                $this->image->setOption( 'jpeg:fancy-upsampling', 'off' );
    374374                        }
    375375
    376                         if ( 'image/png' === $this->mime_type ) {
     376                        elseif ( 'image/png' === $this->mime_type ) {
    377377                                $this->image->setOption( 'png:compression-filter', '5' );
    378378                                $this->image->setOption( 'png:compression-level', '9' );
    379379                                $this->image->setOption( 'png:compression-strategy', '1' );
    380380                                $this->image->setOption( 'png:exclude-chunk', 'all' );
    381381                        }
    382382
     383                        elseif ( 'image/webp' === $this->mime_type ) {
     384                                $this->image->setOption( 'webp:emulate-jpeg-size', true );
     385                        }
     386
    383387                        /*
    384388                         * If alpha channel is not defined, set it opaque.
    385389                         *
    class WP_Image_Editor_Imagick extends WP_Image_Editor { 
    666670                list( $filename, $extension, $mime_type ) = $this->get_output_format( null, $mime_type );
    667671
    668672                try {
     673                        // Render WebP previews as PNG to workaround possible segfault issues.
     674                        if ( 'image/webp' === $mime_type ) {
     675                                $extension = 'PNG';
     676                                $mime_type = 'image/png';
     677                        }
     678
    669679                        // Temporarily change format for stream
    670680                        $this->image->setImageFormat( strtoupper( $extension ) );
    671681
  • src/wp-includes/class-wp-theme.php

    diff --git src/wp-includes/class-wp-theme.php src/wp-includes/class-wp-theme.php
    index 683065cd2f..81fff2091d 100644
    final class WP_Theme implements ArrayAccess { 
    10781078                        return false;
    10791079                }
    10801080
    1081                 foreach ( array( 'png', 'gif', 'jpg', 'jpeg' ) as $ext ) {
     1081                foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp' ) as $ext ) {
    10821082                        if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) {
    10831083                                $this->cache_add( 'screenshot', 'screenshot.' . $ext );
    10841084                                if ( 'relative' == $uri ) {
  • src/wp-includes/compat.php

    diff --git src/wp-includes/compat.php src/wp-includes/compat.php
    index 7377a384c8..7029917568 100644
    endif; 
    505505if ( ! function_exists( 'spl_autoload_register' ) ) {
    506506        require_once ABSPATH . WPINC . '/spl-autoload-compat.php';
    507507}
     508
     509// WebP constants may not be defined, even in cases where the format is supported.
     510if ( ! defined( 'IMAGETYPE_WEBP' ) ) {
     511        define( 'IMAGETYPE_WEBP', 18 );
     512}
     513if ( ! defined( 'IMG_WEBP' ) ) {
     514        define( 'IMG_WEBP', IMAGETYPE_WEBP );
     515}
  • src/wp-includes/customize/class-wp-customize-media-control.php

    diff --git src/wp-includes/customize/class-wp-customize-media-control.php src/wp-includes/customize/class-wp-customize-media-control.php
    index 338324fd36..2160b3a768 100644
    class WP_Customize_Media_Control extends WP_Customize_Control { 
    8686                        if ( $this->setting->default ) {
    8787                                // Fake an attachment model - needs all fields used by template.
    8888                                // Note that the default value must be a URL, NOT an attachment ID.
    89                                 $type               = in_array( substr( $this->setting->default, -3 ), array( 'jpg', 'png', 'gif', 'bmp' ) ) ? 'image' : 'document';
     89                                $type               = preg_match( '/\.(bmp|gif|jpe?g|png|webp)$/i', $this->setting->default ) ? 'image' : 'document';
    9090                                $default_attachment = array(
    9191                                        'id'    => 1,
    9292                                        'url'   => $this->setting->default,
  • src/wp-includes/deprecated.php

    diff --git src/wp-includes/deprecated.php src/wp-includes/deprecated.php
    index 0b3ce28d33..fe1b5048d6 100644
    function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) { 
    19231923        // Do we need to constrain the image?
    19241924        if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) {
    19251925
    1926                 $imagesize = getimagesize($src_file);
     1926                $imagesize = wp_get_image_size($src_file);
    19271927
    19281928                if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) {
    19291929                        $actual_aspect = $imagesize[0] / $imagesize[1];
    function gd_edit_image_support($mime_type) { 
    33113311                                return (imagetypes() & IMG_PNG) != 0;
    33123312                        case 'image/gif':
    33133313                                return (imagetypes() & IMG_GIF) != 0;
     3314                        case 'image/webp':
     3315                                return (imagetypes() & IMG_WEBP) != 0;
    33143316                }
    33153317        } else {
    33163318                switch( $mime_type ) {
    function gd_edit_image_support($mime_type) { 
    33203322                                return function_exists('imagecreatefrompng');
    33213323                        case 'image/gif':
    33223324                                return function_exists('imagecreatefromgif');
     3325                        case 'image/webp':
     3326                                return function_exists('imagecreatefromwebp');
    33233327                }
    33243328        }
    33253329        return false;
  • src/wp-includes/formatting.php

    diff --git src/wp-includes/formatting.php src/wp-includes/formatting.php
    index ce2c851bc5..ab9ec32545 100644
    function translate_smiley( $matches ) { 
    30503050
    30513051        $matches    = array();
    30523052        $ext        = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
    3053         $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
     3053        $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
    30543054
    30553055        // Don't convert smilies that aren't images - they're probably emoji.
    30563056        if ( ! in_array( $ext, $image_exts ) ) {
  • src/wp-includes/functions.php

    diff --git src/wp-includes/functions.php src/wp-includes/functions.php
    index 9b5f292eec..fea62c9009 100644
    function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 
    24072407                                        'image/gif'  => 'gif',
    24082408                                        'image/bmp'  => 'bmp',
    24092409                                        'image/tiff' => 'tif',
     2410                                        'image/webp' => 'webp',
    24102411                                )
    24112412                        );
    24122413
    function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) { 
    24662467        return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes );
    24672468}
    24682469
     2470/**
     2471 * Wrapper for getimagesize()
     2472 *
     2473 * The native PHP function might not support newer formats.
     2474 *
     2475 * @since 5.0
     2476 *
     2477 * @see {https://core.trac.wordpress.org/ticket/35725}
     2478 *
     2479 * @param string $file Full path to the file.
     2480 * @param array $info Additional metadata to pull.
     2481 * @return array|false An array containing width, height, type constant, attributes, and media type.
     2482 */
     2483function wp_get_image_size( $file, &$info = array() ) {
     2484        // Try getimagesize() first.
     2485        if ( false !== ( $info = @getimagesize( $file, $info ) ) ) {
     2486                return $info;
     2487        }
     2488
     2489        // Support for WebP did not land in getimagesize() until PHP 7.1. But that's OK,
     2490        // we can pull what we need from the file headers.
     2491        if ( 'image/webp' === wp_get_image_mime( $file ) ) {
     2492                try {
     2493                        if ( $handle = fopen( $file, 'rb' ) ) {
     2494                                $magic = fread( $handle, 40 );
     2495                                fclose( $handle );
     2496
     2497                                // Make sure we got enough bytes.
     2498                                if ( strlen( $magic ) < 40 ) {
     2499                                        return false;
     2500                                }
     2501
     2502                                $width = $height = false;
     2503
     2504                                // The headers are a little different for each of the three formats.
     2505                                switch ( substr( $magic, 12, 4 ) ) {
     2506                                        // Lossy WebP.
     2507                                        case 'VP8 ':
     2508                                                $parts    = unpack( 'v2', substr( $magic, 26, 4 ) );
     2509                                                $width    = (int) ( $parts[1] & 0x3FFF );
     2510                                                $height   = (int) ( $parts[2] & 0x3FFF );
     2511                                                break;
     2512                                        // Lossless WebP.
     2513                                        case 'VP8L':
     2514                                                $parts    = unpack( 'C4', substr( $magic, 21, 4 ) );
     2515                                                $width    = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
     2516                                                $height   = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) |
     2517                                                                ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
     2518                                                break;
     2519                                        // Animated/alpha WebP.
     2520                                        case 'VP8X':
     2521                                                // Pad 24-bit int.
     2522                                                $width    = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
     2523                                                $width    = (int) ( $width[1] & 0xFFFFFF ) + 1;
     2524
     2525                                                // Pad 24-bit int.
     2526                                                $height   = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
     2527                                                $height   = (int) ( $height[1] & 0xFFFFFF ) + 1;
     2528                                                break;
     2529                                }
     2530
     2531                                // Mimic the native return format.
     2532                                if ( $width && $height ) {
     2533                                        return array(
     2534                                                $width,
     2535                                                $height,
     2536                                                IMAGETYPE_WEBP,
     2537                                                sprintf(
     2538                                                        'width="%d" height="%d"',
     2539                                                        $width,
     2540                                                        $height
     2541                                                ),
     2542                                                'mime'=>'image/webp',
     2543                                        );
     2544                                }
     2545
     2546                                // The image could not be parsed.
     2547                                return false;
     2548                        }
     2549                } catch ( Exception $e ) {
     2550                        return false;
     2551                }
     2552
     2553                return false;
     2554        }
     2555}
     2556
    24692557/**
    24702558 * Returns the real mime type of an image file.
    24712559 *
    function wp_get_image_mime( $file ) { 
    24922580                } else {
    24932581                        $mime = false;
    24942582                }
     2583
     2584                // WebP support took longer to land in Exif than GD.
     2585                if ( ! $mime ) {
     2586                        if ( $handle = fopen( $file, 'rb' ) ) {
     2587                                $magic = bin2hex( fread( $handle, 12 ) );
     2588                                if (
     2589                                        // RIFF.
     2590                                        ( 0 === strpos( $magic, '52494646' ) ) &&
     2591                                        // WEBP.
     2592                                        ( 16 === strpos ( $magic, '57454250' ) )
     2593                                ) {
     2594                                        $mime = 'image/webp';
     2595                                }
     2596                                fclose( $handle );
     2597                        }
     2598                }
    24952599        } catch ( Exception $e ) {
    24962600                $mime = false;
    24972601        }
    function wp_get_mime_types() { 
    25282632                        'bmp'                          => 'image/bmp',
    25292633                        'tiff|tif'                     => 'image/tiff',
    25302634                        'ico'                          => 'image/x-icon',
     2635                        'webp'                         => 'image/webp',
    25312636                        // Video formats.
    25322637                        'asf|asx'                      => 'video/x-ms-asf',
    25332638                        'wmv'                          => 'video/x-ms-wmv',
    function wp_get_ext_types() { 
    26452750         */
    26462751        return apply_filters(
    26472752                'ext2type', array(
    2648                         'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico' ),
     2753                        'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'webp' ),
    26492754                        'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
    26502755                        'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
    26512756                        'document'    => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
  • src/wp-includes/media.php

    diff --git src/wp-includes/media.php src/wp-includes/media.php
    index 393c889ad0..544261cf8c 100644
    function image_downsize( $id, $size = 'medium' ) { 
    227227                $is_intermediate = true;
    228228        } elseif ( $size == 'thumbnail' ) {
    229229                // fall back to the old thumbnail
    230                 if ( ( $thumb_file = wp_get_attachment_thumb_file( $id ) ) && $info = getimagesize( $thumb_file ) ) {
     230                if ( ( $thumb_file = wp_get_attachment_thumb_file( $id ) ) && $info = wp_get_image_size( $thumb_file ) ) {
    231231                        $img_url         = str_replace( $img_url_basename, wp_basename( $thumb_file ), $img_url );
    232232                        $width           = $info[0];
    233233                        $height          = $info[1];
    function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon 
    832832                        $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
    833833
    834834                        $src_file                = $icon_dir . '/' . wp_basename( $src );
    835                         @list( $width, $height ) = getimagesize( $src_file );
     835                        @list( $width, $height ) = wp_get_image_size( $src_file );
    836836                }
    837837
    838838                if ( $src && $width && $height ) {
  • src/wp-includes/post.php

    diff --git src/wp-includes/post.php src/wp-includes/post.php
    index 5ebf42f89d..6dff826b6e 100644
    function wp_attachment_is( $type, $post = null ) { 
    55035503
    55045504        switch ( $type ) {
    55055505                case 'image':
    5506                         $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
     5506                        $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
    55075507                        return in_array( $ext, $image_exts );
    55085508
    55095509                case 'audio':
    function wp_mime_type_icon( $mime = 0 ) { 
    56075607                                                if ( substr( $file, 0, 1 ) == '.' ) {
    56085608                                                        continue;
    56095609                                                }
    5610                                                 if ( ! in_array( strtolower( substr( $file, -4 ) ), array( '.png', '.gif', '.jpg' ) ) ) {
     5610                                                if ( ! preg_match( '/\.(gif|jpe?g|png|webp)$/i', $file ) ) {
    56115611                                                        if ( is_dir( "$dir/$file" ) ) {
    56125612                                                                $dirs[ "$dir/$file" ] = "$uri/$file";
    56135613                                                        }
  • tests/phpunit/tests/functions.php

    diff --git tests/phpunit/data/images/webp-animated.webp tests/phpunit/data/images/webp-animated.webp
    new file mode 100644
    index 0000000000..c60d334a82
    Binary files /dev/null and tests/phpunit/data/images/webp-animated.webp differ
    diff --git tests/phpunit/data/images/webp-lossless.webp tests/phpunit/data/images/webp-lossless.webp
    new file mode 100644
    index 0000000000..7a3a06e0b4
    Binary files /dev/null and tests/phpunit/data/images/webp-lossless.webp differ
    diff --git tests/phpunit/data/images/webp-lossy.webp tests/phpunit/data/images/webp-lossy.webp
    new file mode 100644
    index 0000000000..c8b0e25391
    Binary files /dev/null and tests/phpunit/data/images/webp-lossy.webp differ
    diff --git tests/phpunit/data/images/webp-transparent.webp tests/phpunit/data/images/webp-transparent.webp
    new file mode 100644
    index 0000000000..c4b24a08be
    Binary files /dev/null and tests/phpunit/data/images/webp-transparent.webp differ
    diff --git tests/phpunit/tests/functions.php tests/phpunit/tests/functions.php
    index 52c606537d..bf07f85f54 100644
    class Tests_Functions extends WP_UnitTestCase { 
    11061106                $this->assertEquals( $expected, wp_get_image_mime( $file ) );
    11071107        }
    11081108
     1109        /**
     1110         * @ticket 35725
     1111         * @dataProvider _wp_get_image_size
     1112         */
     1113        public function test_wp_get_image_size( $file, $expected ) {
     1114                if ( ! is_callable( 'exif_imagetype' ) && ! function_exists( 'getimagesize' ) ) {
     1115                        $this->markTestSkipped( 'The exif PHP extension is not loaded.' );
     1116                }
     1117
     1118                $result = wp_get_image_size( $file );
     1119
     1120                // The getimagesize() function varies in its response, so
     1121                // let's restrict comparison to expected keys only.
     1122                if ( is_array( $expected ) ) {
     1123                        foreach ( $expected as $k=>$v ) {
     1124                                $this->assertEquals( true, isset( $result[ $k ] ) );
     1125                                $this->assertEquals( $expected[ $k ], $result[ $k ] );
     1126                        }
     1127                }
     1128                else {
     1129                        $this->assertEquals( $expected, $result );
     1130                }
     1131        }
     1132
    11091133        /**
    11101134         * @ticket 39550
    11111135         * @dataProvider _wp_check_filetype_and_ext_data
    class Tests_Functions extends WP_UnitTestCase { 
    12031227                                DIR_TESTDATA . '/images/test-image-mime-jpg.png',
    12041228                                'image/jpeg',
    12051229                        ),
     1230                        // Animated WebP.
     1231                        array(
     1232                                DIR_TESTDATA . '/images/webp-animated.webp',
     1233                                'image/webp',
     1234                        ),
     1235                        // Lossless WebP.
     1236                        array(
     1237                                DIR_TESTDATA . '/images/webp-lossless.webp',
     1238                                'image/webp',
     1239                        ),
     1240                        // Lossy WebP.
     1241                        array(
     1242                                DIR_TESTDATA . '/images/webp-lossy.webp',
     1243                                'image/webp',
     1244                        ),
     1245                        // Transparent WebP.
     1246                        array(
     1247                                DIR_TESTDATA . '/images/webp-transparent.webp',
     1248                                'image/webp',
     1249                        ),
     1250                        // Not an image.
     1251                        array(
     1252                                DIR_TESTDATA . '/uploads/dashicons.woff',
     1253                                false,
     1254                        ),
     1255                );
     1256
     1257                return $data;
     1258        }
     1259
     1260        /**
     1261         * Data profider for test_wp_get_image_size();
     1262         */
     1263        public function _wp_get_image_size() {
     1264                $data = array(
     1265                        // Standard JPEG.
     1266                        array(
     1267                                DIR_TESTDATA . '/images/test-image.jpg',
     1268                                array(
     1269                                        50,
     1270                                        50,
     1271                                        IMAGETYPE_JPEG,
     1272                                        'width="50" height="50"',
     1273                                        'mime' => 'image/jpeg',
     1274                                ),
     1275                        ),
     1276                        // Standard GIF.
     1277                        array(
     1278                                DIR_TESTDATA . '/images/test-image.gif',
     1279                                array(
     1280                                        50,
     1281                                        50,
     1282                                        IMAGETYPE_GIF,
     1283                                        'width="50" height="50"',
     1284                                        'mime' => 'image/gif',
     1285                                ),
     1286                        ),
     1287                        // Standard PNG.
     1288                        array(
     1289                                DIR_TESTDATA . '/images/test-image.png',
     1290                                array(
     1291                                        50,
     1292                                        50,
     1293                                        IMAGETYPE_PNG,
     1294                                        'width="50" height="50"',
     1295                                        'mime' => 'image/png',
     1296                                ),
     1297                        ),
     1298                        // Image with wrong extension.
     1299                        array(
     1300                                DIR_TESTDATA . '/images/test-image-mime-jpg.png',
     1301                                array(
     1302                                        50,
     1303                                        50,
     1304                                        IMAGETYPE_JPEG,
     1305                                        'width="50" height="50"',
     1306                                        'mime' => 'image/jpeg',
     1307                                ),
     1308                        ),
     1309                        // Animated WebP.
     1310                        array(
     1311                                DIR_TESTDATA . '/images/webp-animated.webp',
     1312                                array(
     1313                                        100,
     1314                                        100,
     1315                                        IMAGETYPE_WEBP,
     1316                                        'width="100" height="100"',
     1317                                        'mime' => 'image/webp',
     1318                                ),
     1319                        ),
     1320                        // Lossless WebP.
     1321                        array(
     1322                                DIR_TESTDATA . '/images/webp-lossless.webp',
     1323                                array(
     1324                                        1200,
     1325                                        675,
     1326                                        IMAGETYPE_WEBP,
     1327                                        'width="1200" height="675"',
     1328                                        'mime' => 'image/webp',
     1329                                ),
     1330                        ),
     1331                        // Lossy WebP.
     1332                        array(
     1333                                DIR_TESTDATA . '/images/webp-lossy.webp',
     1334                                array(
     1335                                        1200,
     1336                                        675,
     1337                                        IMAGETYPE_WEBP,
     1338                                        'width="1200" height="675"',
     1339                                        'mime' => 'image/webp',
     1340                                ),
     1341                        ),
     1342                        // Transparent WebP.
     1343                        array(
     1344                                DIR_TESTDATA . '/images/webp-transparent.webp',
     1345                                array(
     1346                                        1200,
     1347                                        675,
     1348                                        IMAGETYPE_WEBP,
     1349                                        'width="1200" height="675"',
     1350                                        'mime' => 'image/webp',
     1351                                ),
     1352                        ),
    12061353                        // Not an image.
    12071354                        array(
    12081355                                DIR_TESTDATA . '/uploads/dashicons.woff',
  • tests/phpunit/tests/image/functions.php

    diff --git tests/phpunit/tests/image/functions.php tests/phpunit/tests/image/functions.php
    index f36fe6fdc6..2c0254c27d 100644
    class Tests_Image_Functions extends WP_UnitTestCase { 
    5959                        'test-image.psd',
    6060                        'test-image-zip.tiff',
    6161                        'test-image.jpg',
     62                        'webp-animated.webp',
     63                        'webp-lossless.webp',
     64                        'webp-lossy.webp',
     65                        'webp-transparent.webp',
    6266                );
    6367
    6468                foreach ( $files as $file ) {
    class Tests_Image_Functions extends WP_UnitTestCase { 
    8589                        'test-image.gif',
    8690                        'test-image.png',
    8791                        'test-image.jpg',
     92                        'webp-animated.webp',
     93                        'webp-lossless.webp',
     94                        'webp-lossy.webp',
     95                        'webp-transparent.webp',
    8896                );
    8997
    9098                foreach ( $files as $file ) {
    class Tests_Image_Functions extends WP_UnitTestCase { 
    130138                        'image/jpeg',
    131139                        'image/gif',
    132140                        'image/png',
     141                        'image/webp',
    133142                );
    134143
    135144                // Test each image editor engine
    class Tests_Image_Functions extends WP_UnitTestCase { 
    222231                        'jpe'  => 'image/jpeg',
    223232                        'gif'  => 'image/gif',
    224233                        'png'  => 'image/png',
     234                        'webp' => 'image/webp',
    225235                        'unk'  => 'image/jpeg', // Default, unknown
    226236                );
    227237