rfc:ext-gd-2.4

PHP RFC: Update ext/gd to latest features

Introduction

Add and expose libgd's 2.4 features:

* New codecs and codecs completeness

  • QOI (builtin)
  • JXL, full support, including animations (uses libjxl)
  • UHDR (uses libultrahdr)
  • GIF, added full support, animations, read and write (builtin)
  • BMP, added full support but OS/2 bmp (builtin)
  • webp, full support for all formats and animations (use libwebp)
  • TIFF. full support, single or multiple pages, read and write
  • PNG, full support for all formats, add with options (extending the imagepng($im, $basefilter) exposing all options
  • for formats supporting, ability to read/write metadata as raw data, which can be then processed (libexif, pure php, etc) and used back to write the image)

* New 2D vector APIs * Perceptual Diff (can finally be used for more arch resilient tests in php)

Proposal

Expose new libgd features and enhancement to ext/gd

  • new codecs
  • new 2D vector drawing APIs (canvas-like)
  • Ability to do more resilient testing from php

Examples

2D Vector APIs

Gradient modes and compositions

Some drawings

Backward Incompatible Changes

Color match fix breaks BC as the correct behavior is implemented now

Correct FT rendering and BBox on angle, baseline etc. affects slightly bounding box on axis aligned texts, and significantly more on rotated texts. The bug in the FT2 implementations actually prevented accurate rendering.

Codecs

PNG

<?php
 
/**
 * @generate-class-entries
 * @generate-c-enums
 */
 
namespace Gd\Codec {
    /** @strict-properties */
    class CodecException extends \RuntimeException
    {
    }
}
 
namespace Gd\Png {
#ifdef HAVE_GD_PNG_WRITE_OPTIONS
    enum Filter
    {
        case None;
        case Sub;
        case Up;
        case Average;
        case Paeth;
    }
 
    enum CompressionStrategy
    {
        case Default;
        case Filtered;
        case HuffmanOnly;
        case Rle;
        case Fixed;
    }
 
    /** @strict-properties */
    final readonly class WriteOptions
    {
        public int $compressionLevel;
        public array $filters;
        public CompressionStrategy $compressionStrategy;
 
        /** @param list<Filter> $filters */
        public function __construct(
            int $compressionLevel = -1,
            array $filters = [],
            CompressionStrategy $compressionStrategy = CompressionStrategy::Default,
        ) {}
    }
 
    final class Codec
    {
        private function __construct() {}
 
        public static function toFile(
            \GdImage $image,
            string $path,
            WriteOptions $options = new WriteOptions(),
        ): void {}
 
        /** @param resource $stream */
        public static function toStream(
            \GdImage $image,
            $stream,
            WriteOptions $options = new WriteOptions(),
        ): void {}
 
        public static function toString(
            \GdImage $image,
            WriteOptions $options = new WriteOptions(),
        ): string {}
    }
#endif
}
<?php
 
/**
 * @generate-class-entries
 * @generate-c-enums
 */
 
namespace Gd\Codec {
    /** @strict-properties */
    class CodecException extends \RuntimeException
    {
    }
}
 
namespace Gd\Qoi {
#ifdef HAVE_GD_QOI
    enum Colorspace
    {
        case SRGB;
        case Linear;
    }
 
    final class Codec
    {
        private function __construct() {}
 
        public static function fromFile(string $path): \GdImage {}
 
        /** @param resource $stream */
        public static function fromStream($stream): \GdImage {}
 
        public static function fromString(string $bytes): \GdImage {}
 
        public static function toFile(
            \GdImage $image,
            string $path,
            Colorspace $colorspace = Colorspace::SRGB,
        ): void {}
 
        /** @param resource $stream */
        public static function toStream(
            \GdImage $image,
            $stream,
            Colorspace $colorspace = Colorspace::SRGB,
        ): void {}
 
        public static function toString(
            \GdImage $image,
            Colorspace $colorspace = Colorspace::SRGB,
        ): string {}
    }
#endif
}

Proposed PHP Version(s)

PHP 8.6.0

RFC Impact

To the Ecosystem

New APIs exposed, no new syntax.

To Existing Extensions

ext/gd

Open Issues

Make sure there are no open issues when the vote starts!

Future Scope

latest libgd prepares the road to libgd 3.0 which adds more internal buffer formats and ability to handle HDR natively. Fromats like actual 32bits ARGB, floating points buffers, etc.

Voting Choices

Pick a title that reflects the concrete choice people will vote on.

Please consult the php/policies repository for the current voting guidelines.


Primary Vote requiring a 2/3 majority to accept the RFC:

Implement $feature as outlined in the RFC?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

There are two separate PRs:

    1. The winbuilds already include the new dependencyes
  1. The additions and changes to ext/gd once the sync is merged is not yet pushed

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.

rfc/ext-gd-2.4.txt · Last modified: by pajoye