diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/class-wp-image-editor-gd.php --- a/wp/wp-includes/class-wp-image-editor-gd.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/class-wp-image-editor-gd.php Fri Sep 05 18:40:08 2025 +0200 @@ -64,13 +64,15 @@ $image_types = imagetypes(); switch ( $mime_type ) { case 'image/jpeg': - return ( $image_types & IMG_JPG ) != 0; + return ( $image_types & IMG_JPG ) !== 0; case 'image/png': - return ( $image_types & IMG_PNG ) != 0; + return ( $image_types & IMG_PNG ) !== 0; case 'image/gif': - return ( $image_types & IMG_GIF ) != 0; + return ( $image_types & IMG_GIF ) !== 0; case 'image/webp': - return ( $image_types & IMG_WEBP ) != 0; + return ( $image_types & IMG_WEBP ) !== 0; + case 'image/avif': + return ( $image_types & IMG_AVIF ) !== 0 && function_exists( 'imageavif' ); } return false; @@ -111,6 +113,16 @@ $this->image = @imagecreatefromstring( $file_contents ); } + // AVIF may not work with imagecreatefromstring(). + if ( + function_exists( 'imagecreatefromavif' ) && + ( 'image/avif' === wp_get_image_mime( $this->file ) ) + ) { + $this->image = @imagecreatefromavif( $this->file ); + } else { + $this->image = @imagecreatefromstring( $file_contents ); + } + if ( ! is_gd_image( $this->image ) ) { return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file ); } @@ -163,13 +175,20 @@ * * @since 3.5.0 * - * @param int|null $max_w Image width. - * @param int|null $max_h Image height. - * @param bool $crop + * @param int|null $max_w Image width. + * @param int|null $max_h Image height. + * @param bool|array $crop { + * Optional. Image cropping behavior. If false, the image will be scaled (default). + * If true, image will be cropped to the specified dimensions using center positions. + * If an array, the image will be cropped using the array to specify the crop location: + * + * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. + * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. + * } * @return true|WP_Error */ public function resize( $max_w, $max_h, $crop = false ) { - if ( ( $this->size['width'] == $max_w ) && ( $this->size['height'] == $max_h ) ) { + if ( ( $this->size['width'] === $max_w ) && ( $this->size['height'] === $max_h ) ) { return true; } @@ -190,7 +209,14 @@ /** * @param int $max_w * @param int $max_h - * @param bool|array $crop + * @param bool|array $crop { + * Optional. Image cropping behavior. If false, the image will be scaled (default). + * If true, image will be cropped to the specified dimensions using center positions. + * If an array, the image will be cropped using the array to specify the crop location: + * + * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. + * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. + * } * @return resource|GdImage|WP_Error */ protected function _resize( $max_w, $max_h, $crop = false ) { @@ -236,9 +262,9 @@ * @type array ...$0 { * Array of height, width values, and whether to crop. * - * @type int $width Image width. Optional if `$height` is specified. - * @type int $height Image height. Optional if `$width` is specified. - * @type bool $crop Optional. Whether to crop the image. Default false. + * @type int $width Image width. Optional if `$height` is specified. + * @type int $height Image height. Optional if `$width` is specified. + * @type bool|array $crop Optional. Whether to crop the image. Default false. * } * } * @return array An array of resized images' metadata by size. @@ -265,9 +291,9 @@ * @param array $size_data { * Array of size data. * - * @type int $width The maximum width in pixels. - * @type int $height The maximum height in pixels. - * @type bool $crop Whether to crop the image to exact dimensions. + * @type int $width The maximum width in pixels. + * @type int $height The maximum height in pixels. + * @type bool|array $crop Whether to crop the image to exact dimensions. * } * @return array|WP_Error The image data array for inclusion in the `sizes` array in the image meta, * WP_Error object on error. @@ -324,8 +350,10 @@ * @return true|WP_Error */ public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = null, $src_abs = false ) { - // If destination width/height isn't specified, - // use same as width/height from source. + /* + * If destination width/height isn't specified, + * use same as width/height from source. + */ if ( ! $dst_w ) { $dst_w = $src_w; } @@ -425,10 +453,20 @@ * @since 3.5.0 * @since 5.9.0 Renamed `$filename` to `$destfilename` to match parent class * for PHP 8 named parameter support. + * @since 6.0.0 The `$filesize` value was added to the returned array. * * @param string|null $destfilename Optional. Destination filename. Default null. * @param string|null $mime_type Optional. The mime-type. Default null. - * @return array|WP_Error {'path'=>string, 'file'=>string, 'width'=>int, 'height'=>int, 'mime-type'=>string} + * @return array|WP_Error { + * Array on success or WP_Error if the file failed to save. + * + * @type string $path Path to the image file. + * @type string $file Name of the image file. + * @type int $width Image width. + * @type int $height Image height. + * @type string $mime-type The mime type of the image. + * @type int $filesize File size of the image. + * } */ public function save( $destfilename = null, $mime_type = null ) { $saved = $this->_save( $this->image, $destfilename, $mime_type ); @@ -442,10 +480,22 @@ } /** + * @since 3.5.0 + * @since 6.0.0 The `$filesize` value was added to the returned array. + * * @param resource|GdImage $image * @param string|null $filename * @param string|null $mime_type - * @return array|WP_Error + * @return array|WP_Error { + * Array on success or WP_Error if the file failed to save. + * + * @type string $path Path to the image file. + * @type string $file Name of the image file. + * @type int $width Image width. + * @type int $height Image height. + * @type string $mime-type The mime type of the image. + * @type int $filesize File size of the image. + * } */ protected function _save( $image, $filename = null, $mime_type = null ) { list( $filename, $extension, $mime_type ) = $this->get_output_format( $filename, $mime_type ); @@ -454,6 +504,18 @@ $filename = $this->generate_filename( null, null, $extension ); } + if ( function_exists( 'imageinterlace' ) ) { + /** + * Filters whether to output progressive images (if available). + * + * @since 6.5.0 + * + * @param bool $interlace Whether to use progressive images for output if available. Default false. + * @param string $mime_type The mime type being saved. + */ + imageinterlace( $image, apply_filters( 'image_save_progressive', false, $mime_type ) ); + } + if ( 'image/gif' === $mime_type ) { if ( ! $this->make_image( $filename, 'imagegif', array( $image, $filename ) ) ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); @@ -471,8 +533,16 @@ if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); } - } elseif ( 'image/webp' == $mime_type ) { - if ( ! function_exists( 'imagewebp' ) || ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) ) { + } elseif ( 'image/webp' === $mime_type ) { + if ( ! function_exists( 'imagewebp' ) + || ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) + ) { + return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); + } + } elseif ( 'image/avif' === $mime_type ) { + if ( ! function_exists( 'imageavif' ) + || ! $this->make_image( $filename, 'imageavif', array( $image, $filename, $this->get_quality() ) ) + ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); } } else { @@ -523,8 +593,17 @@ if ( function_exists( 'imagewebp' ) ) { header( 'Content-Type: image/webp' ); return imagewebp( $this->image, null, $this->get_quality() ); + } else { + // Fall back to JPEG. + header( 'Content-Type: image/jpeg' ); + return imagejpeg( $this->image, null, $this->get_quality() ); } - // Fall back to the default if webp isn't supported. + case 'image/avif': + if ( function_exists( 'imageavif' ) ) { + header( 'Content-Type: image/avif' ); + return imageavif( $this->image, null, $this->get_quality() ); + } + // Fall back to JPEG. default: header( 'Content-Type: image/jpeg' ); return imagejpeg( $this->image, null, $this->get_quality() );