WordPress.org

Make WordPress Core

Changeset 50810


Ignore:
Timestamp:
05/04/2021 02:43:36 PM (6 months ago)
Author:
adamsilverstein
Message:

Images: enable WebP support.

Add support for uploading, editing and saving WebP images when supported by the server.

Add 'image/webp' to supported mime types. Correctly identify WebP images and sizes even when PHP doesn't support WebP. Resize uploaded WebP files (when supported) and use for front end markup.

Props markoheijne, blobfolio, Clorith, joemcgill, atjn, desrosj, spacedmonkey, marylauc, mikeschroder, hellofromtonya, flixos90.
Fixes #35725.

Location:
trunk
Files:
5 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/image-edit.php

    r50560 r50810  
    307307                header( 'Content-Type: image/gif' );
    308308                return imagegif( $image );
     309            case 'image/webp':
     310                if ( function_exists( 'imagewebp' ) ) {
     311                    header( 'Content-Type: image/webp' );
     312                    return imagewebp( $image, null, 90 );
     313                }
     314                return false;
    309315            default:
    310316                return false;
     
    392398            case 'image/gif':
    393399                return imagegif( $image, $filename );
     400            case 'image/webp':
     401                if ( function_exists( 'imagewebp' ) ) {
     402                    return imagewebp( $image, $filename );
     403                }
     404                return false;
    394405            default:
    395406                return false;
  • trunk/src/wp-admin/includes/image.php

    r50552 r50810  
    517517                case 'image/png':
    518518                    $ext = '.png';
     519                    break;
     520                case 'image/webp':
     521                    $ext = '.webp';
    519522                    break;
    520523            }
     
    914917 */
    915918function file_is_displayable_image( $path ) {
    916     $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO );
     919    $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
    917920
    918921    $info = wp_getimagesize( $path );
     
    963966        case 'image/gif':
    964967            $image = imagecreatefromgif( $filepath );
     968            break;
     969        case 'image/webp':
     970            $image = false;
     971            if ( function_exists( 'imagecreatefromwebp' ) ) {
     972                $image = imagecreatefromwebp( $filepath );
     973            }
    965974            break;
    966975        default:
  • trunk/src/wp-admin/includes/media.php

    r50541 r50810  
    994994    if ( ! empty( $file ) ) {
    995995
    996         $allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif' );
     996        $allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif', 'webp' );
    997997
    998998        /**
  • trunk/src/wp-admin/includes/schema.php

    r49581 r50810  
    12161216        'png',
    12171217        'gif',
     1218        'webp',
    12181219        // Video.
    12191220        'mov',
  • trunk/src/wp-includes/class-wp-image-editor-gd.php

    r50146 r50810  
    7070            case 'image/gif':
    7171                return ( $image_types & IMG_GIF ) != 0;
     72            case 'image/webp':
     73                return ( $image_types & IMG_WEBP ) != 0; // phpcs:ignore PHPCompatibility.Constants.NewConstants.img_webpFound
    7274        }
    7375
     
    100102        }
    101103
    102         $this->image = @imagecreatefromstring( $file_contents );
     104        // WebP may not work with imagecreatefromstring().
     105        if (
     106            function_exists( 'imagecreatefromwebp' ) &&
     107            ( 'image/webp' === wp_get_image_mime( $this->file ) )
     108        ) {
     109            $this->image = @imagecreatefromwebp( $this->file );
     110        } else {
     111            $this->image = @imagecreatefromstring( $file_contents );
     112        }
    103113
    104114        if ( ! is_gd_image( $this->image ) ) {
     
    458468        } elseif ( 'image/jpeg' === $mime_type ) {
    459469            if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) {
     470                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
     471            }
     472        } elseif ( 'image/webp' == $mime_type ) {
     473            if ( ! function_exists( 'imagewebp' ) || ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) ) {
    460474                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    461475            }
     
    503517                header( 'Content-Type: image/gif' );
    504518                return imagegif( $this->image );
     519            case 'image/webp':
     520                if ( function_exists( 'imagewebp' ) ) {
     521                    header( 'Content-Type: image/webp' );
     522                    return imagewebp( $this->image, null, $this->get_quality() );
     523                }
     524                // Fall back to the default if webp isn't supported.
    505525            default:
    506526                header( 'Content-Type: image/jpeg' );
  • trunk/src/wp-includes/class-wp-image-editor-imagick.php

    r49927 r50810  
    198198
    199199        try {
    200             if ( 'image/jpeg' === $this->mime_type ) {
    201                 $this->image->setImageCompressionQuality( $quality );
    202                 $this->image->setImageCompression( imagick::COMPRESSION_JPEG );
    203             } else {
    204                 $this->image->setImageCompressionQuality( $quality );
     200            switch ( $this->mime_type ) {
     201                case 'image/jpeg':
     202                    $this->image->setImageCompressionQuality( $quality );
     203                    $this->image->setImageCompression( imagick::COMPRESSION_JPEG );
     204                    break;
     205                case 'image/webp':
     206                    if ( _wp_webp_is_lossy( $this->file ) ) {
     207                        $this->image->setImageCompressionQuality( $quality );
     208                    } else {
     209                        // Use WebP lossless settings.
     210                        $this->image->setImageCompressionQuality( 100 );
     211                        $this->image->setOption( 'webp:lossless', 'true' );
     212                    }
     213                    break;
     214                default:
     215                    $this->image->setImageCompressionQuality( $quality );
    205216            }
    206217        } catch ( Exception $e ) {
    207218            return new WP_Error( 'image_quality_error', $e->getMessage() );
    208219        }
    209 
    210220        return true;
    211221    }
     222
    212223
    213224    /**
  • trunk/src/wp-includes/class-wp-theme.php

    r50505 r50810  
    11421142        }
    11431143
    1144         foreach ( array( 'png', 'gif', 'jpg', 'jpeg' ) as $ext ) {
     1144        foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp' ) as $ext ) {
    11451145            if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) {
    11461146                $this->cache_add( 'screenshot', 'screenshot.' . $ext );
  • trunk/src/wp-includes/compat.php

    r49193 r50810  
    371371    }
    372372}
     373
     374// WebP constants may not be defined, even in cases where the format is supported.
     375if ( ! defined( 'IMAGETYPE_WEBP' ) ) {
     376    define( 'IMAGETYPE_WEBP', 18 );
     377}
     378if ( ! defined( 'IMG_WEBP' ) ) {
     379    define( 'IMG_WEBP', IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
     380}
  • trunk/src/wp-includes/customize/class-wp-customize-media-control.php

    r50556 r50810  
    9292                // Note that the default value must be a URL, NOT an attachment ID.
    9393                $ext  = substr( $this->setting->default, -3 );
    94                 $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp' ), true ) ? 'image' : 'document';
     94                $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp' ), true ) ? 'image' : 'document';
    9595
    9696                $default_attachment = array(
  • trunk/src/wp-includes/deprecated.php

    r50146 r50810  
    33413341            case 'image/gif':
    33423342                return (imagetypes() & IMG_GIF) != 0;
     3343            case 'image/webp':
     3344                return (imagetypes() & IMG_WEBP) != 0; // phpcs:ignore PHPCompatibility.Constants.NewConstants.img_webpFound
    33433345        }
    33443346    } else {
     
    33503352            case 'image/gif':
    33513353                return function_exists('imagecreatefromgif');
     3354            case 'image/webp':
     3355                return function_exists('imagecreatefromwebp');
    33523356        }
    33533357    }
  • trunk/src/wp-includes/formatting.php

    r49968 r50810  
    33193319    $matches    = array();
    33203320    $ext        = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
    3321     $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
     3321    $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
    33223322
    33233323    // Don't convert smilies that aren't images - they're probably emoji.
  • trunk/src/wp-includes/functions.php

    r50505 r50810  
    28872887                    'image/bmp'  => 'bmp',
    28882888                    'image/tiff' => 'tif',
     2889                    'image/webp' => 'webp',
    28892890                )
    28902891            );
     
    30643065            $mime = false;
    30653066        }
     3067
     3068        if ( false !== $mime ) {
     3069            return $mime;
     3070        }
     3071
     3072        $handle = fopen( $file, 'rb' );
     3073        if ( false === $handle ) {
     3074            return false;
     3075        }
     3076
     3077        $magic = fread( $handle, 12 );
     3078        if ( false === $magic ) {
     3079            return false;
     3080        }
     3081
     3082        // Add WebP fallback detection when image library doesn't support WebP.
     3083        // Note: detection values come from LibWebP, see
     3084        // https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30
     3085        $magic = bin2hex( $magic );
     3086        if (
     3087            // RIFF.
     3088            ( 0 === strpos( $magic, '52494646' ) ) &&
     3089            // WEBP.
     3090            ( 16 === strpos( $magic, '57454250' ) )
     3091        ) {
     3092            $mime = 'image/webp';
     3093        }
     3094
     3095        fclose( $handle );
    30663096    } catch ( Exception $e ) {
    30673097        $mime = false;
     
    31023132            'bmp'                          => 'image/bmp',
    31033133            'tiff|tif'                     => 'image/tiff',
     3134            'webp'                         => 'image/webp',
    31043135            'ico'                          => 'image/x-icon',
    31053136            'heic'                         => 'image/heic',
     
    32233254        'ext2type',
    32243255        array(
    3225             'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic' ),
     3256            'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp' ),
    32263257            'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
    32273258            'video'       => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
  • trunk/src/wp-includes/media.php

    r50682 r50810  
    49814981 *
    49824982 * @since 5.7.0
     4983 * @since 5.8.0 Added support for WebP images.
    49834984 *
    49844985 * @param string $filename   The file path.
     
    49954996    ) {
    49964997        if ( 2 === func_num_args() ) {
    4997             return getimagesize( $filename, $image_info );
     4998            return _wp_get_image_size( $filename, $image_info );
    49984999        } else {
    4999             return getimagesize( $filename );
     5000            return _wp_get_image_size( $filename );
    50005001        }
    50015002    }
     
    50125013    if ( 2 === func_num_args() ) {
    50135014        // phpcs:ignore WordPress.PHP.NoSilencedErrors
    5014         return @getimagesize( $filename, $image_info );
     5015        return @_wp_get_image_size( $filename, $image_info );
    50155016    } else {
    50165017        // phpcs:ignore WordPress.PHP.NoSilencedErrors
    5017         return @getimagesize( $filename );
    5018     }
    5019 }
     5018        return @_wp_get_image_size( $filename );
     5019    }
     5020}
     5021
     5022/**
     5023 * Extracts meta information about a webp file: width, height and type.
     5024 *
     5025 * @since 5.8.0
     5026 *
     5027 * @param [type] $filename Path to a WebP file.
     5028 * @return array $webp_info {
     5029 *     An array of WebP image information.
     5030 *
     5031 *     @type array $size {
     5032 *         @type int  $width  Image width.
     5033 *         @type int  $height Image height.
     5034 *         @type bool $type   The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
     5035 *     }
     5036 */
     5037function wp_get_webp_info( $filename ) {
     5038    $width  = false;
     5039    $height = false;
     5040    $type   = false;
     5041    if ( ! 'image/webp' === wp_get_image_mime( $filename ) ) {
     5042        return compact( 'width', 'height', 'type' );
     5043    }
     5044    try {
     5045        $handle = fopen( $filename, 'rb' );
     5046        if ( $handle ) {
     5047            $magic = fread( $handle, 40 );
     5048            fclose( $handle );
     5049
     5050            // Make sure we got enough bytes.
     5051            if ( strlen( $magic ) < 40 ) {
     5052                return compact( 'width', 'height', 'type' );
     5053            }
     5054
     5055            // The headers are a little different for each of the three formats.
     5056            // Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
     5057            switch ( substr( $magic, 12, 4 ) ) {
     5058                // Lossy WebP.
     5059                case 'VP8 ':
     5060                    $parts  = unpack( 'v2', substr( $magic, 26, 4 ) );
     5061                    $width  = (int) ( $parts[1] & 0x3FFF );
     5062                    $height = (int) ( $parts[2] & 0x3FFF );
     5063                    $type   = 'lossy';
     5064                    break;
     5065                // Lossless WebP.
     5066                case 'VP8L':
     5067                    $parts  = unpack( 'C4', substr( $magic, 21, 4 ) );
     5068                    $width  = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
     5069                    $height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
     5070                    $type   = 'lossless';
     5071                    break;
     5072                // Animated/alpha WebP.
     5073                case 'VP8X':
     5074                    // Pad 24-bit int.
     5075                    $width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
     5076                    $width = (int) ( $width[1] & 0xFFFFFF ) + 1;
     5077                    // Pad 24-bit int.
     5078                    $height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
     5079                    $height = (int) ( $height[1] & 0xFFFFFF ) + 1;
     5080                    $type   = 'animated-alpha';
     5081                    break;
     5082            }
     5083        }
     5084    } catch ( Exception $e ) {
     5085    }
     5086    return compact( 'width', 'height', 'type' );
     5087}
     5088
     5089/**
     5090 * Determines if a passed image is a lossy WebP image.
     5091 *
     5092 * @since 5.8.0
     5093 *
     5094 * @param string $filename The file path.
     5095 * @return bool Whether the file is a lossy WebP file.
     5096 */
     5097function _wp_webp_is_lossy( $filename ) {
     5098    $webp_info = wp_get_webp_info( $filename );
     5099    $type      = $webp_info['type'];
     5100    return $type && 'lossy' === $type;
     5101}
     5102
     5103/**
     5104 * Gets the image size, with support for WebP images.
     5105 *
     5106 * @since 5.8.0
     5107 * @access private
     5108 *
     5109 * @param string $filename  The file path.
     5110 * @param array  $imageinfo Extended image information, passed by reference.
     5111 * @return array|false Array of image information or false on failure.
     5112 */
     5113function _wp_get_image_size( $filename, &$imageinfo = array() ) {
     5114    // Try getimagesize() first.
     5115    $info = getimagesize( $filename, $imageinfo );
     5116    if ( false !== $info ) {
     5117        return $info;
     5118    }
     5119    // For PHP versions that don't support WebP images, extract the image
     5120    // size info from the file headers.
     5121    if ( 'image/webp' === wp_get_image_mime( $filename ) ) {
     5122        $webp_info = wp_get_webp_info( $filename );
     5123        $width     = $webp_info['width'];
     5124        $height    = $webp_info['height'];
     5125
     5126            // Mimic the native return format.
     5127        if ( $width && $height ) {
     5128            return array(
     5129                $width,
     5130                $height,
     5131                IMAGETYPE_WEBP, // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
     5132                sprintf(
     5133                    'width="%d" height="%d"',
     5134                    $width,
     5135                    $height
     5136                ),
     5137                'mime' => 'image/webp',
     5138            );
     5139        }
     5140    }
     5141
     5142    // The image could not be parsed.
     5143    return false;
     5144}
  • trunk/src/wp-includes/post.php

    r50761 r50810  
    65406540    switch ( $type ) {
    65416541        case 'image':
    6542             $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
     6542            $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
    65436543            return in_array( $ext, $image_exts, true );
    65446544
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    r50152 r50810  
    439439        }
    440440
    441         $supported_types = array( 'image/jpeg', 'image/png', 'image/gif' );
     441        $supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp' );
    442442        $mime_type       = get_post_mime_type( $attachment_id );
    443443        if ( ! in_array( $mime_type, $supported_types, true ) ) {
  • trunk/tests/phpunit/tests/functions.php

    r50284 r50810  
    12271227
    12281228    /**
     1229     * @ticket 35725
     1230     * @dataProvider data_wp_getimagesize
     1231     */
     1232    public function test_wp_getimagesize( $file, $expected ) {
     1233        if ( ! is_callable( 'exif_imagetype' ) && ! function_exists( 'getimagesize' ) ) {
     1234            $this->markTestSkipped( 'The exif PHP extension is not loaded.' );
     1235        }
     1236
     1237        $result = wp_getimagesize( $file );
     1238
     1239        // The getimagesize() function varies in its response, so
     1240        // let's restrict comparison to expected keys only.
     1241        if ( is_array( $expected ) ) {
     1242            foreach ( $expected as $k => $v ) {
     1243                $this->assertEquals( true, isset( $result[ $k ] ) );
     1244                $this->assertEquals( $expected[ $k ], $result[ $k ] );
     1245            }
     1246        } else {
     1247            $this->assertEquals( $expected, $result );
     1248        }
     1249    }
     1250
     1251    /**
    12291252     * @ticket 39550
    12301253     * @dataProvider _wp_check_filetype_and_ext_data
     
    13131336                DIR_TESTDATA . '/images/test-image-mime-jpg.png',
    13141337                'image/jpeg',
     1338            ),
     1339            // Animated WebP.
     1340            array(
     1341                DIR_TESTDATA . '/images/webp-animated.webp',
     1342                'image/webp',
     1343            ),
     1344            // Lossless WebP.
     1345            array(
     1346                DIR_TESTDATA . '/images/webp-lossless.webp',
     1347                'image/webp',
     1348            ),
     1349            // Lossy WebP.
     1350            array(
     1351                DIR_TESTDATA . '/images/webp-lossy.webp',
     1352                'image/webp',
     1353            ),
     1354            // Transparent WebP.
     1355            array(
     1356                DIR_TESTDATA . '/images/webp-transparent.webp',
     1357                'image/webp',
     1358            ),
     1359            // Not an image.
     1360            array(
     1361                DIR_TESTDATA . '/uploads/dashicons.woff',
     1362                false,
     1363            ),
     1364        );
     1365
     1366        return $data;
     1367    }
     1368
     1369    /**
     1370     * Data profider for test_wp_getimagesize();
     1371     */
     1372    public function data_wp_getimagesize() {
     1373        $data = array(
     1374            // Standard JPEG.
     1375            array(
     1376                DIR_TESTDATA . '/images/test-image.jpg',
     1377                array(
     1378                    50,
     1379                    50,
     1380                    IMAGETYPE_JPEG,
     1381                    'width="50" height="50"',
     1382                    'mime' => 'image/jpeg',
     1383                ),
     1384            ),
     1385            // Standard GIF.
     1386            array(
     1387                DIR_TESTDATA . '/images/test-image.gif',
     1388                array(
     1389                    50,
     1390                    50,
     1391                    IMAGETYPE_GIF,
     1392                    'width="50" height="50"',
     1393                    'mime' => 'image/gif',
     1394                ),
     1395            ),
     1396            // Standard PNG.
     1397            array(
     1398                DIR_TESTDATA . '/images/test-image.png',
     1399                array(
     1400                    50,
     1401                    50,
     1402                    IMAGETYPE_PNG,
     1403                    'width="50" height="50"',
     1404                    'mime' => 'image/png',
     1405                ),
     1406            ),
     1407            // Image with wrong extension.
     1408            array(
     1409                DIR_TESTDATA . '/images/test-image-mime-jpg.png',
     1410                array(
     1411                    50,
     1412                    50,
     1413                    IMAGETYPE_JPEG,
     1414                    'width="50" height="50"',
     1415                    'mime' => 'image/jpeg',
     1416                ),
     1417            ),
     1418            // Animated WebP.
     1419            array(
     1420                DIR_TESTDATA . '/images/webp-animated.webp',
     1421                array(
     1422                    100,
     1423                    100,
     1424                    IMAGETYPE_WEBP,
     1425                    'width="100" height="100"',
     1426                    'mime' => 'image/webp',
     1427                ),
     1428            ),
     1429            // Lossless WebP.
     1430            array(
     1431                DIR_TESTDATA . '/images/webp-lossless.webp',
     1432                array(
     1433                    1200,
     1434                    675,
     1435                    IMAGETYPE_WEBP,
     1436                    'width="1200" height="675"',
     1437                    'mime' => 'image/webp',
     1438                ),
     1439            ),
     1440            // Lossy WebP.
     1441            array(
     1442                DIR_TESTDATA . '/images/webp-lossy.webp',
     1443                array(
     1444                    1200,
     1445                    675,
     1446                    IMAGETYPE_WEBP,
     1447                    'width="1200" height="675"',
     1448                    'mime' => 'image/webp',
     1449                ),
     1450            ),
     1451            // Transparent WebP.
     1452            array(
     1453                DIR_TESTDATA . '/images/webp-transparent.webp',
     1454                array(
     1455                    1200,
     1456                    675,
     1457                    IMAGETYPE_WEBP,
     1458                    'width="1200" height="675"',
     1459                    'mime' => 'image/webp',
     1460                ),
    13151461            ),
    13161462            // Not an image.
  • trunk/tests/phpunit/tests/image/editor.php

    r50449 r50810  
    196196        $this->assertSame( '100x50', $editor->get_suffix() );
    197197    }
     198
     199    /**
     200     * Test wp_get_webp_info.
     201     *
     202     * @ticket 35725
     203     * @dataProvider _test_wp_get_webp_info
     204     *
     205     */
     206    public function test_wp_get_webp_info( $file, $expected ) {
     207        $editor = wp_get_image_editor( $file );
     208        if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/webp' ) ) {
     209            $this->markTestSkipped( sprintf( 'Skipping test: no WebP support in the editor engine %s on this system.', $this->editor_engine ) );
     210        } else {
     211            $file_data = wp_get_webp_info( $file );
     212            $this->assertSame( $file_data, $expected );
     213        }
     214    }
     215
     216    /**
     217     * Data provider for test_wp_get_webp_info();
     218     */
     219    public function _test_wp_get_webp_info() {
     220        return array(
     221            // Standard JPEG.
     222            array(
     223                DIR_TESTDATA . '/images/test-image.jpg',
     224                array(
     225                    'width'  => false,
     226                    'height' => false,
     227                    'type'   => false,
     228                ),
     229            ),
     230            // Standard GIF.
     231            array(
     232                DIR_TESTDATA . '/images/test-image.gif',
     233                array(
     234                    'width'  => false,
     235                    'height' => false,
     236                    'type'   => false,
     237                ),
     238            ),
     239            // Animated WebP.
     240            array(
     241                DIR_TESTDATA . '/images/webp-animated.webp',
     242                array(
     243                    'width'  => 100,
     244                    'height' => 100,
     245                    'type'   => 'animated-alpha',
     246                ),
     247            ),
     248            // Lossless WebP.
     249            array(
     250                DIR_TESTDATA . '/images/webp-lossless.webp',
     251                array(
     252                    'width'  => 1200,
     253                    'height' => 675,
     254                    'type'   => 'lossless',
     255                ),
     256            ),
     257            // Lossy WebP.
     258            array(
     259                DIR_TESTDATA . '/images/webp-lossy.webp',
     260                array(
     261                    'width'  => 1200,
     262                    'height' => 675,
     263                    'type'   => 'lossy',
     264                ),
     265            ),
     266            // Transparent WebP.
     267            array(
     268                DIR_TESTDATA . '/images/webp-transparent.webp',
     269                array(
     270                    'width'  => 1200,
     271                    'height' => 675,
     272                    'type'   => 'animated-alpha',
     273                ),
     274            ),
     275        );
     276    }
     277
    198278}
  • trunk/tests/phpunit/tests/image/functions.php

    r49450 r50810  
    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
     
    9296            'test-image.jpg',
    9397        );
     98
     99        // Add WebP images if the image editor supports them.
     100        $file   = DIR_TESTDATA . '/images/test-image.webp';
     101        $editor = wp_get_image_editor( $file );
     102        if ( ( ! is_wp_error( $editor ) ) && $editor->supports_mime_type( 'image/webp' ) ) {
     103            $files = array_merge(
     104                $files,
     105                array(
     106                    'webp-animated.webp',
     107                    'webp-lossless.webp',
     108                    'webp-lossy.webp',
     109                    'webp-transparent.webp',
     110                )
     111            );
     112        }
    94113
    95114        // IMAGETYPE_ICO is only defined in PHP 5.3+.
     
    175194        );
    176195
     196        // Include WebP in tests when platform supports it.
     197        if ( function_exists( 'imagewebp' ) ) {
     198            array_push( $mime_types, 'image/webp' );
     199        }
     200
    177201        // Test each image editor engine.
    178202        foreach ( $classes as $class ) {
     
    271295            'gif'  => 'image/gif',
    272296            'png'  => 'image/png',
    273             'unk'  => 'image/jpeg', // Default, unknown.
     297            'webp' => 'image/webp',
     298            'unk'  => 'image/jpeg',   // Default, unknown.
    274299        );
    275300
  • trunk/tests/phpunit/tests/image/resize.php

    r50463 r50810  
    6565    }
    6666
     67    function test_resize_webp() {
     68        $file   = DIR_TESTDATA . '/images/test-image.webp';
     69        $editor = wp_get_image_editor( $file );
     70
     71        // Check if the editor supports the webp mime type.
     72        if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/webp' ) ) {
     73            $this->markTestSkipped( sprintf( 'Skipping test: no WebP support in the editor engine %s on this system.', $this->editor_engine ) );
     74        } else {
     75            $image = $this->resize_helper( $file, 25, 25 );
     76            $this->assertSame( 'test-image-25x25.webp', wp_basename( $image ) );
     77            list($w, $h, $type) = wp_getimagesize( $image );
     78            $this->assertSame( 25, $w );
     79            $this->assertSame( 25, $h );
     80            $this->assertSame( IMAGETYPE_WEBP, $type );
     81            unlink( $image );
     82        }
     83    }
     84
    6785    function test_resize_larger() {
    6886        // image_resize() should refuse to make an image larger.
Note: See TracChangeset for help on using the changeset viewer.