Make WordPress Core

Changeset 57524


Ignore:
Timestamp:
02/02/2024 05:46:50 PM (3 years ago)
Author:
adamsilverstein
Message:

Media: enable AVIF support.

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

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

Props adamsilverstein, lukefiretoss, ayeshrajans, navjotjsingh, Tyrannous, jb510, gregbenz, nickpagz, JavierCasares, mukesh27, yguyon, swissspidy.
Fixes #51228.

Location:
trunk
Files:
7 added
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/phpcs.xml.dist

    r57264 r57524  
    6060        <exclude-pattern>/src/wp-includes/class-simplepie\.php</exclude-pattern>
    6161        <exclude-pattern>/src/wp-includes/class-snoopy\.php</exclude-pattern>
     62        <exclude-pattern>/src/wp-includes/class-avif-info\.php</exclude-pattern>
    6263        <exclude-pattern>/src/wp-includes/deprecated\.php</exclude-pattern>
    6364        <exclude-pattern>/src/wp-includes/ms-deprecated\.php</exclude-pattern>
  • trunk/src/js/_enqueues/vendor/plupload/handlers.js

    r57231 r57524  
    609609                                        up.removeFile( file );
    610610                                        return;
     611                                } else if ( file.type === 'image/avif' && up.settings.avif_upload_error ) {
     612                                        // Disallow uploading of AVIF images if the server cannot edit them.
     613                                        wpQueueError( pluploadL10n.noneditable_image );
     614                                        up.removeFile( file );
     615                                        return;
    611616                                }
    612617
  • trunk/src/js/_enqueues/vendor/plupload/wp-plupload.js

    r54085 r57524  
    364364                                        up.removeFile( file );
    365365                                        return;
     366                                } else if ( file.type === 'image/avif' && up.settings.avif_upload_error ) {
     367                                        // Disallow uploading of AVIF images if the server cannot edit them.
     368                                        error( pluploadL10n.noneditable_image, {}, file, 'no-retry' );
     369                                        up.removeFile( file );
     370                                        return;
    366371                                }
    367372
  • trunk/src/js/_enqueues/vendor/thickbox/thickbox.js

    r53451 r57524  
    7777           }
    7878
    79            var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$|\.webp$/;
     79           var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$|\.webp$|\.avif$/;
    8080           var urlType = baseURL.toLowerCase().match(urlString);
    8181
     
    8585                        urlType == '.gif' ||
    8686                        urlType == '.bmp' ||
    87                         urlType == '.webp'
     87                        urlType == '.webp' ||
     88                        urlType == '.avif'
    8889                ){//code to show images
    8990
  • trunk/src/js/media/controllers/library.js

    r52073 r57524  
    197197                // If uploading, we know the filename but not the mime type.
    198198                if ( attachment.get('uploading') ) {
    199                         return /\.(jpe?g|png|gif|webp)$/i.test( attachment.get('filename') );
     199                        return /\.(jpe?g|png|gif|webp|avif)$/i.test( attachment.get('filename') );
    200200                }
    201201
  • trunk/src/wp-admin/includes/image-edit.php

    r56653 r57524  
    391391                                }
    392392                                return false;
     393                        case 'image/avif':
     394                                if ( function_exists( 'imageavif' ) ) {
     395                                        header( 'Content-Type: image/avif' );
     396                                        return imageavif( $image, null, 90 );
     397                                }
     398                                return false;
    393399                        default:
    394400                                return false;
     
    493499                                if ( function_exists( 'imagewebp' ) ) {
    494500                                        return imagewebp( $image, $filename );
     501                                }
     502                                return false;
     503                        case 'image/avif':
     504                                if ( function_exists( 'imageavif' ) ) {
     505                                        return imageavif( $image, $filename );
    495506                                }
    496507                                return false;
  • trunk/src/wp-admin/includes/image.php

    r57267 r57524  
    10071007 */
    10081008function file_is_displayable_image( $path ) {
    1009         $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP );
     1009        $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP, IMAGETYPE_AVIF );
    10101010
    10111011        $info = wp_getimagesize( $path );
  • trunk/src/wp-admin/includes/media.php

    r57181 r57524  
    21992199        }
    22002200
     2201        // Check if AVIF images can be edited.
     2202        if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {
     2203                $plupload_init['avif_upload_error'] = true;
     2204        }
     2205
    22012206        /**
    22022207         * Filters the default Plupload settings.
  • trunk/src/wp-admin/includes/schema.php

    r57389 r57524  
    12511251                'gif',
    12521252                'webp',
     1253                'avif',
    12531254                // Video.
    12541255                'mov',
  • trunk/src/wp-includes/class-wp-image-editor-gd.php

    r56418 r57524  
    7272                        case 'image/webp':
    7373                                return ( $image_types & IMG_WEBP ) != 0;
     74                        case 'image/avif':
     75                                return ( $image_types & IMG_AVIF ) != 0;
    7476                }
    7577
     
    112114                }
    113115
     116                // AVIF may not work with imagecreatefromstring().
     117                if (
     118                        function_exists( 'imagecreatefromavif' ) &&
     119                        ( 'image/avif' === wp_get_image_mime( $this->file ) )
     120                ) {
     121                        $this->image = @imagecreatefromavif( $this->file );
     122                } else {
     123                        $this->image = @imagecreatefromstring( $file_contents );
     124                }
     125
    114126                if ( ! is_gd_image( $this->image ) ) {
    115127                        return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file );
     
    512524                } elseif ( 'image/webp' == $mime_type ) {
    513525                        if ( ! function_exists( 'imagewebp' ) || ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) ) {
     526                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
     527                        }
     528                } elseif ( 'image/avif' == $mime_type ) {
     529                        if ( ! function_exists( 'imageavif' ) || ! $this->make_image( $filename, 'imageavif', array( $image, $filename, $this->get_quality() ) ) ) {
    514530                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    515531                        }
     
    562578                                        header( 'Content-Type: image/webp' );
    563579                                        return imagewebp( $this->image, null, $this->get_quality() );
     580                                } else {
     581                                        // Fall back to JPEG.
     582                                        header( 'Content-Type: image/jpeg' );
     583                                        return imagejpeg( $this->image, null, $this->get_quality() );
    564584                                }
    565                                 // Fall back to the default if webp isn't supported.
     585                        case 'image/avif':
     586                                if ( function_exists( 'imageavif' ) ) {
     587                                        header( 'Content-Type: image/avif' );
     588                                        return imageavif( $this->image, null, $this->get_quality() );
     589                                }
     590                                // Fall back to JPEG.
    566591                        default:
    567592                                header( 'Content-Type: image/jpeg' );
  • trunk/src/wp-includes/class-wp-image-editor-imagick.php

    r56547 r57524  
    220220                                        }
    221221                                        break;
     222                                case 'image/avif':
    222223                                default:
    223224                                        $this->image->setImageCompressionQuality( $quality );
     
    255256                if ( ! $height ) {
    256257                        $height = $size['height'];
     258                }
     259
     260                /*
     261                 * If we still don't have the image size, fall back to `wp_getimagesize`. This ensures AVIF images
     262                 * are properly sized without affecting previous `getImageGeometry` behavior.
     263                 */
     264                if ( ( ! $width || ! $height ) && 'image/avif' === $this->mime_type ) {
     265                        $size   = wp_getimagesize( $this->file );
     266                        $width  = $size[0];
     267                        $height = $size[1];
    257268                }
    258269
  • trunk/src/wp-includes/class-wp-image-editor.php

    r56536 r57524  
    319319                                break;
    320320                        case 'image/jpeg':
     321                        case 'image/avif':
    321322                        default:
    322323                                $quality = $this->default_quality;
  • trunk/src/wp-includes/class-wp-theme.php

    r56978 r57524  
    12641264                }
    12651265
    1266                 foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp' ) as $ext ) {
     1266                foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp', 'avif' ) as $ext ) {
    12671267                        if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) {
    12681268                                $this->cache_add( 'screenshot', 'screenshot.' . $ext );
  • trunk/src/wp-includes/compat.php

    r57337 r57524  
    530530        define( 'IMG_WEBP', IMAGETYPE_WEBP );
    531531}
     532
     533// IMAGETYPE_AVIF constant is only defined in PHP 8.x or later.
     534if ( ! defined( 'IMAGETYPE_AVIF' ) ) {
     535        define( 'IMAGETYPE_AVIF', 19 );
     536}
     537
     538// IMG_AVIF constant is only defined in PHP 8.x or later.
     539if ( ! defined( 'IMG_AVIF' ) ) {
     540        define( 'IMG_AVIF', IMAGETYPE_AVIF );
     541}
  • trunk/src/wp-includes/customize/class-wp-customize-media-control.php

    r56193 r57524  
    9494                                 */
    9595                                $ext  = substr( $this->setting->default, -3 );
    96                                 $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp' ), true ) ? 'image' : 'document';
     96                                $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document';
    9797
    9898                                $default_attachment = array(
  • trunk/src/wp-includes/deprecated.php

    r57511 r57524  
    33373337                        case 'image/webp':
    33383338                                return (imagetypes() & IMG_WEBP) != 0;
    3339                 }
     3339                        case 'image/avif':
     3340                                return (imagetypes() & IMG_AVIF) != 0;
     3341                        }
    33403342        } else {
    33413343                switch( $mime_type ) {
     
    33483350                        case 'image/webp':
    33493351                                return function_exists('imagecreatefromwebp');
     3352                        case 'image/avif':
     3353                                return function_exists('imagecreatefromavif');
    33503354                }
    33513355        }
  • trunk/src/wp-includes/formatting.php

    r57302 r57524  
    34653465        $matches    = array();
    34663466        $ext        = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
    3467         $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
     3467        $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif' );
    34683468
    34693469        // Don't convert smilies that aren't images - they're probably emoji.
  • trunk/src/wp-includes/functions.php

    r57509 r57524  
    31183118                                        'image/tiff' => 'tif',
    31193119                                        'image/webp' => 'webp',
     3120                                        'image/avif' => 'avif',
    31203121                                )
    31213122                        );
     
    32963297 * @since 4.7.1
    32973298 * @since 5.8.0 Added support for WebP images.
     3299 * @since 6.5.0 Added support for AVIF images.
    32983300 *
    32993301 * @param string $file Full path to the file.
     
    33503352                        $mime = 'image/webp';
    33513353                }
     3354
     3355                /**
     3356                 * Add AVIF fallback detection when image library doesn't support AVIF.
     3357                 *
     3358                 * Detection based on section 4.3.1 File-type box definition of the ISO/IEC 14496-12
     3359                 * specification and the AV1-AVIF spec, see https://aomediacodec.github.io/av1-avif/v1.1.0.html#brands.
     3360                 */
     3361
     3362                 // Divide the header string into 4 byte groups.
     3363                $magic = str_split( $magic, 8 );
     3364
     3365                if (
     3366                        isset( $magic[1] ) &&
     3367                        isset( $magic[2] ) &&
     3368                        'ftyp' === hex2bin( $magic[1] ) &&
     3369                        ( 'avif' === hex2bin( $magic[2] ) || 'avis' === hex2bin( $magic[2] ) )
     3370                ) {
     3371                        $mime = 'image/avif';
     3372                }
    33523373        } catch ( Exception $e ) {
    33533374                $mime = false;
     
    33893410                        'tiff|tif'                     => 'image/tiff',
    33903411                        'webp'                         => 'image/webp',
     3412                        'avif'                         => 'image/avif',
    33913413                        'ico'                          => 'image/x-icon',
    33923414                        'heic'                         => 'image/heic',
     
    35103532                'ext2type',
    35113533                array(
    3512                         'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp' ),
     3534                        'image'       => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp', 'avif' ),
    35133535                        'audio'       => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
    35143536                        '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

    r57294 r57524  
    41014101        require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
    41024102        require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
     4103        require_once ABSPATH . WPINC . '/class-avif-info.php';
    41034104        /**
    41044105         * Filters the list of image editing library classes.
     
    42034204        if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
    42044205                $defaults['webp_upload_error'] = true;
     4206        }
     4207
     4208        // Check if AVIF images can be edited.
     4209        if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {
     4210                $defaults['avif_upload_error'] = true;
    42054211        }
    42064212
     
    54815487 * @since 5.7.0
    54825488 * @since 5.8.0 Added support for WebP images.
     5489 * @since 6.5.0 Added support for AVIF images.
    54835490 *
    54845491 * @param string $filename   The file path.
     
    55135520        }
    55145521
    5515         if ( false !== $info ) {
     5522        if (
     5523                ! empty( $info ) &&
     5524                // Some PHP versions return 0x0 sizes from `getimagesize` for unrecognized image formats, including AVIFs.
     5525                ! ( empty( $info[0] ) && empty( $info[1] ) )
     5526        ) {
    55165527                return $info;
    55175528        }
     
    55425553        }
    55435554
     5555        // For PHP versions that don't support AVIF images, extract the image size info from the file headers.
     5556        if ( 'image/avif' === wp_get_image_mime( $filename ) ) {
     5557                $avif_info = wp_get_avif_info( $filename );
     5558
     5559                $width  = $avif_info['width'];
     5560                $height = $avif_info['height'];
     5561
     5562                // Mimic the native return format.
     5563                if ( $width && $height ) {
     5564                        return array(
     5565                                $width,
     5566                                $height,
     5567                                IMAGETYPE_AVIF,
     5568                                sprintf(
     5569                                        'width="%d" height="%d"',
     5570                                        $width,
     5571                                        $height
     5572                                ),
     5573                                'mime' => 'image/avif',
     5574                        );
     5575                }
     5576        }
     5577
    55445578        // The image could not be parsed.
    55455579        return false;
     5580}
     5581
     5582/**
     5583 * Extracts meta information about an AVIF file: width, height, bit depth, and number of channels.
     5584 *
     5585 * @since 6.5.0
     5586 *
     5587 * @param string $filename Path to an AVIF file.
     5588 * @return array {
     5589 *    An array of AVIF image information.
     5590 *
     5591 *    @type int|false $width        Image width on success, false on failure.
     5592 *    @type int|false $height       Image height on success, false on failure.
     5593 *    @type int|false $bit_depth    Image bit depth on success, false on failure.
     5594 *    @type int|false $num_channels Image number of channels on success, false on failure.
     5595 * }
     5596 */
     5597function wp_get_avif_info( $filename ) {
     5598        $results = array(
     5599                'width'        => false,
     5600                'height'       => false,
     5601                'bit_depth'    => false,
     5602                'num_channels' => false,
     5603        );
     5604
     5605        if ( 'image/avif' !== wp_get_image_mime( $filename ) ) {
     5606                return $results;
     5607        }
     5608
     5609        // Parse the file using libavifinfo's PHP implementation.
     5610        require_once ABSPATH . WPINC . '/class-avif-info.php';
     5611
     5612        $handle = fopen( $filename, 'rb' );
     5613        if ( $handle ) {
     5614                $parser  = new Avifinfo\Parser( $handle );
     5615                $success = $parser->parse_ftyp() && $parser->parse_file();
     5616                fclose( $handle );
     5617                if ( $success ) {
     5618                        $results = $parser->features->primary_item_features;
     5619                }
     5620        }
     5621        return $results;
    55465622}
    55475623
  • trunk/src/wp-includes/post.php

    r57273 r57524  
    67016701        switch ( $type ) {
    67026702                case 'image':
    6703                         $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
     6703                        $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif' );
    67046704                        return in_array( $ext, $image_exts, true );
    67056705
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    r57380 r57524  
    457457                }
    458458
    459                 $supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp' );
     459                $supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif' );
    460460                $mime_type       = get_post_mime_type( $attachment_id );
    461461                if ( ! in_array( $mime_type, $supported_types, true ) ) {
  • trunk/tests/phpunit/tests/functions.php

    r57284 r57524  
    13711371                                false,
    13721372                        ),
     1373                        // Animated AVIF.
     1374                        array(
     1375                                DIR_TESTDATA . '/images/avif-animated.avif',
     1376                                'image/avif',
     1377                        ),
     1378                        // Lossless AVIF.
     1379                        array(
     1380                                DIR_TESTDATA . '/images/avif-lossless.avif',
     1381                                'image/avif',
     1382                        ),
     1383                        // Lossy AVIF.
     1384                        array(
     1385                                DIR_TESTDATA . '/images/avif-lossy.avif',
     1386                                'image/avif',
     1387                        ),
     1388                        // Transparent AVIF.
     1389                        array(
     1390                                DIR_TESTDATA . '/images/avif-transparent.avif',
     1391                                'image/avif',
     1392                        ),
    13731393                );
    13741394
     
    14961516                                DIR_TESTDATA . '/uploads/dashicons.woff',
    14971517                                false,
     1518                        ),
     1519                        // Animated AVIF.
     1520                        array(
     1521                                DIR_TESTDATA . '/images/avif-animated.avif',
     1522                                array(
     1523                                        150,
     1524                                        150,
     1525                                        IMAGETYPE_AVIF,
     1526                                        'width="150" height="150"',
     1527                                        'mime' => 'image/avif',
     1528                                ),
     1529                        ),
     1530                        // Lossless AVIF.
     1531                        array(
     1532                                DIR_TESTDATA . '/images/avif-lossless.avif',
     1533                                array(
     1534                                        400,
     1535                                        400,
     1536                                        IMAGETYPE_AVIF,
     1537                                        'width="400" height="400"',
     1538                                        'mime' => 'image/avif',
     1539                                ),
     1540                        ),
     1541                        // Lossy AVIF.
     1542                        array(
     1543                                DIR_TESTDATA . '/images/avif-lossy.avif',
     1544                                array(
     1545                                        400,
     1546                                        400,
     1547                                        IMAGETYPE_AVIF,
     1548                                        'width="400" height="400"',
     1549                                        'mime' => 'image/avif',
     1550                                ),
     1551                        ),
     1552                        // Transparent AVIF.
     1553                        array(
     1554                                DIR_TESTDATA . '/images/avif-transparent.avif',
     1555                                array(
     1556                                        128,
     1557                                        128,
     1558                                        IMAGETYPE_AVIF,
     1559                                        'width="128" height="128"',
     1560                                        'mime' => 'image/avif',
     1561                                ),
    14981562                        ),
    14991563                );
  • trunk/tests/phpunit/tests/image/editor.php

    r56547 r57524  
    293293         */
    294294        public function test_wp_get_webp_info( $file, $expected ) {
    295                 $editor = wp_get_image_editor( $file );
    296 
    297                 if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/webp' ) ) {
    298                         $this->markTestSkipped( sprintf( 'No WebP support in the editor engine %s on this system.', $this->editor_engine ) );
    299                 }
    300 
    301295                $file_data = wp_get_webp_info( $file );
    302296                $this->assertSame( $expected, $file_data );
     
    364358                );
    365359        }
     360
     361        /**
     362         * Test wp_get_avif_info.
     363         *
     364         * @ticket 51228
     365         *
     366         * @dataProvider data_wp_get_avif_info
     367         *
     368         * @param string $file     The path to the AVIF file for testing.
     369         * @param array  $expected The expected AVIF file information.
     370         */
     371        public function test_wp_get_avif_info( $file, $expected ) {
     372                $file_data = wp_get_avif_info( $file );
     373                $this->assertSame( $expected, $file_data );
     374        }
     375
     376        /**
     377         * Data provider for test_wp_get_avif_info().
     378         */
     379        public function data_wp_get_avif_info() {
     380                return array(
     381                        // Standard JPEG.
     382                        array(
     383                                DIR_TESTDATA . '/images/test-image.jpg',
     384                                array(
     385                                        'width'        => false,
     386                                        'height'       => false,
     387                                        'bit_depth'    => false,
     388                                        'num_channels' => false,
     389                                ),
     390                        ),
     391                        // Standard GIF.
     392                        array(
     393                                DIR_TESTDATA . '/images/test-image.gif',
     394                                array(
     395                                        'width'        => false,
     396                                        'height'       => false,
     397                                        'bit_depth'    => false,
     398                                        'num_channels' => false,
     399                                ),
     400                        ),
     401                        // Animated AVIF.
     402                        array(
     403                                DIR_TESTDATA . '/images/avif-animated.avif',
     404                                array(
     405                                        'width'        => 150,
     406                                        'height'       => 150,
     407                                        'bit_depth'    => 8,
     408                                        'num_channels' => 4,
     409                                ),
     410                        ),
     411                        // Lossless AVIF.
     412                        array(
     413                                DIR_TESTDATA . '/images/avif-lossless.avif',
     414                                array(
     415                                        'width'        => 400,
     416                                        'height'       => 400,
     417                                        'bit_depth'    => 8,
     418                                        'num_channels' => 3,
     419                                ),
     420                        ),
     421                        // Lossy AVIF.
     422                        array(
     423                                DIR_TESTDATA . '/images/avif-lossy.avif',
     424                                array(
     425                                        'width'        => 400,
     426                                        'height'       => 400,
     427                                        'bit_depth'    => 8,
     428                                        'num_channels' => 3,
     429                                ),
     430                        ),
     431                        // Transparent AVIF.
     432                        array(
     433                                DIR_TESTDATA . '/images/avif-transparent.avif',
     434                                array(
     435                                        'width'        => 128,
     436                                        'height'       => 128,
     437                                        'bit_depth'    => 12,
     438                                        'num_channels' => 4,
     439                                ),
     440                        ),
     441                        array(
     442                                DIR_TESTDATA . '/images/color_grid_alpha_nogrid.avif',
     443                                array(
     444                                        'width'        => 80,
     445                                        'height'       => 80,
     446                                        'bit_depth'    => 8,
     447                                        'num_channels' => 4,
     448                                ),
     449                        ),
     450                        array(
     451                                DIR_TESTDATA . '/images/colors_hdr_p3.avif',
     452                                array(
     453                                        'width'        => 200,
     454                                        'height'       => 200,
     455                                        'bit_depth'    => 10,
     456                                        'num_channels' => 3,
     457                                ),
     458                        ),
     459                );
     460        }
    366461}
  • trunk/tests/phpunit/tests/image/functions.php

    r56559 r57524  
    112112                        'webp-lossy.webp',
    113113                        'webp-transparent.webp',
     114                        'avif-animated.avif',
     115                        'avif-lossless.avif',
     116                        'avif-lossy.avif',
     117                        'avif-transparent.avif',
    114118                );
    115119
     
    185189                        $files[] = 'webp-lossy.webp';
    186190                        $files[] = 'webp-transparent.webp';
     191                }
     192
     193                // Add AVIF images if the image editor supports them.
     194                $file   = DIR_TESTDATA . '/images/avif-lossless.avif';
     195                $editor = wp_get_image_editor( $file );
     196
     197                if ( ! is_wp_error( $editor ) && $editor->supports_mime_type( 'image/avif' ) ) {
     198                        $files[] = 'avif-animated.avif';
     199                        $files[] = 'avif-lossless.avif';
     200                        $files[] = 'avif-lossy.avif';
     201                        $files[] = 'avif-transparent.avif';
    187202                }
    188203
  • trunk/tests/phpunit/tests/image/resize.php

    r54226 r57524  
    8989        }
    9090
     91        /**
     92         * Test resizing AVIF image.
     93         *
     94         * @ticket 51228
     95         */
     96        public function test_resize_avif() {
     97                $file   = DIR_TESTDATA . '/images/avif-lossy.avif';
     98                $editor = wp_get_image_editor( $file );
     99
     100                // Check if the editor supports the avif mime type.
     101                if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/avif' ) ) {
     102                        $this->markTestSkipped( sprintf( 'No AVIF support in the editor engine %s on this system.', $this->editor_engine ) );
     103                }
     104
     105                $image = $this->resize_helper( $file, 25, 25 );
     106
     107                list( $w, $h, $type ) = wp_getimagesize( $image );
     108
     109                unlink( $image );
     110
     111                $this->assertSame( 'avif-lossy-25x25.avif', wp_basename( $image ) );
     112                $this->assertSame( 25, $w );
     113                $this->assertSame( 25, $h );
     114                $this->assertSame( IMAGETYPE_AVIF, $type );
     115        }
     116
    91117        public function test_resize_larger() {
    92118                // image_resize() should refuse to make an image larger.
Note: See TracChangeset for help on using the changeset viewer.