Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124383 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id D6F491A00B7 for ; Thu, 11 Jul 2024 09:35:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1720690612; bh=PcBwQ5gGOL1sY4zSeWaM51A3/pwWi1TXpRZ0CWpzc2s=; h=From:Date:Subject:To:From; b=B4Q5dPIv7EbT5fMSYu0slYILTvUVGxJImqiUGkrkTV9EMRTZCyk3fCsETWiiFTJ/l j9XeoZ1qoebYJUCemWiTgqhE8H7LQQpfs0yOvOypOvyRmtbjLIRUA1T7o1dcexN3XW +lpwFLm09rCLMWDJ/VDxpEogu1YBhfn7yLGTmvtA5S3y/aRVgx9CMaLn2fVAMj2f54 2S8dvYN0kH3M+PUSr7R7dh+HJ69uDWFM8RxNam68xrMZGtcyYZQJgrc2bIINoH+K/u QAQW7lXOb88RUz8G+z7zM+Rg7JW4WqK8CkCHAx8JOFZM5ac5F0BuNUzx+GGvt21DLk UNwsrxNXnnTuw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9A40C18005C for ; Thu, 11 Jul 2024 09:36:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from venus.thgnet.it (venus.thgnet.it [159.69.22.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 11 Jul 2024 09:36:50 +0000 (UTC) Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) by venus.thgnet.it (Postfix) with ESMTPSA id 1A7B53E5D5 for ; Thu, 11 Jul 2024 11:35:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=giacobbi.net; s=venus; t=1720690523; bh=PcBwQ5gGOL1sY4zSeWaM51A3/pwWi1TXpRZ0CWpzc2s=; h=From:Date:Subject:To:From; b=Ww+vYbDUV9w94b/vBNmKs5nWTx14EzWbPfgnzy9lhLuE7ZNPEq6f22HSUREjdqpF8 2W/0Chs6ZeBzpPZGinj+EQ/C0Ap+kvu/zb5Ba0/cKwAQJWyBEdkgWtDD4h9ZvgtDTk aTgqqs/lLS0S/+jcwR9GNvHfmdQ1kmRxDmOqCai4= Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-a77dc08db60so77548966b.1 for ; Thu, 11 Jul 2024 02:35:23 -0700 (PDT) X-Gm-Message-State: AOJu0Yzny0U1GIJniKhBWeMqSG90ozF3v0JpW27JKP2k1rBM1snzku+J c2FVOO0QvXkfw79N1r6VkI/TU+svtGB1Hsb9ubNyKZRwU8+eZIktuudXL0qdhRT2glGO2Dq33wp 5jTuxNNRLJPzBw/DodNn+WBUQ5VE= X-Google-Smtp-Source: AGHT+IFAUs8wfrIytCG+0q4bGzm5UUG05D3ln2bJ8m4Xjwt15LnbCVfzb1YVrmPbb96nicPxjBRUC6QtAjTav1dpJN4= X-Received: by 2002:a17:906:198e:b0:a72:42df:cd27 with SMTP id a640c23a62f3a-a780b89d502mr516014566b.71.1720690522742; Thu, 11 Jul 2024 02:35:22 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 Date: Thu, 11 Jul 2024 11:35:11 +0200 X-Gmail-Original-Message-ID: Message-ID: Subject: [PHP-DEV] ext/gd new imagematch function (was: adding imagecompare) To: PHP Internals List Content-Type: multipart/alternative; boundary="000000000000606bed061cf57bef" From: giovanni@giacobbi.net (Giovanni Giacobbi) --000000000000606bed061cf57bef Content-Type: text/plain; charset="UTF-8" The recent PR #14877 [1] proposes to add the imagecompare gd function that mimics the gdImageCompare function from libgd. I always thought that a pixel-by-pixel matching function for two images was a big missing feature in PHP, as the corresponding userland implementation is really, REALLY slow. The problem with gdImageCompare is that it checks several aspects of the two images, and fails on its core purpose. The behavior is better seen in its source code [2] rather than explained. I see the following problems: - The gdImageCompare is kind of buggy, as it completely disregards the alpha channel. As a user, I would expect that two images that have a pixel rgba(255, 0, 0, 100%) and one rgba(255, 0, 0, 50%) are considered different, but the current implementation reports them as identical. - Checking for bitmasks is cumbersome, and it requires 9 new constants in the global namespace (the IMG_CMP_*), which are nearly useless. Most use cases will just want to check for this: imagecompare($im1, $im2) & IMG_CMP_IMAGE. - The checks in gdImageCompare are also a bit arbitrary, why compare the interlace flag but not the palette order? Why check the number of colors in the palette if they are not even used in the image? - If a user is interested in the other checks, they can all be implemented in userland with existing functions: imageinterlace, imagecolortransparent, imageistruecolor, imagesx, imagesy, imagecolorstotal. I believe PHP should only offer required building blocks and leave to the libraries the implementation of more structured functionality. My proposal is a completely different function called imagematch() that solves the exact problem of the pixel-by-pixel matching, with the added value of optionally matching portions of the images, using the following signature: function imagematch(GdImage $image1, GdImage $image2, int $x1 = 0, int $y1 = 0, int $x2 = 0, int $y2 = 0, ?int $width = null, ?int $height = null): bool {} I already drafted PR #14914 [3] with the first two parameters. There is not an equivalent libgd implementation, so the implementation is entirely on the php side, but as you can see it's quite trivial. Even with the extended functionality of matching portions of the images it would be just a few extra lines of code, so not a big maintenance burden. If an RFC is required, I'm happy to redact it after the initial feedback round. [1] https://github.com/php/php-src/pull/14877 [2] https://github.com/php/php-src/blob/5586d0c7de00acbfb217e1c6321da918b96ef960/ext/gd/libgd/gd.c#L2834 [3] https://github.com/php/php-src/pull/14914 --000000000000606bed061cf57bef Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
The recent PR #14877 [1] proposes to add the imagecompare= =C2=A0gd function that mimics the gdImageCompare function from libgd. I alw= ays thought that a pixel-by-pixel matching function for two images was a bi= g missing feature in PHP, as the corresponding userland implementation is r= eally, REALLY slow.

The problem with gdImageCompare is t= hat it checks several aspects of the two images, and fails on its core purp= ose. The behavior is better seen in its source code [2] rather than explain= ed. I see the following problems:
- The gdImageCompare is kind of= buggy, as it completely disregards the alpha channel. As a user, I would e= xpect that two images that have a pixel rgba(255, 0, 0, 100%) and one rgba(= 255, 0, 0, 50%) are considered different, but the current implementation re= ports them as identical.
- Checking for bitmasks is cumbersome, a= nd it requires 9 new constants in the global namespace (the IMG_CMP_*), whi= ch are nearly useless. Most use cases will just want to check for this: ima= gecompare($im1, $im2) & IMG_CMP_IMAGE.
- The checks in gdImag= eCompare are also a bit arbitrary, why compare the interlace flag but not t= he palette order? Why check the number of colors in the palette if they are= not even used in the image?
- If a user is interested in the=C2= =A0other checks, they can all be implemented in userland with existing func= tions: imageinterlace, imagecolortransparent, imageistruecolor, imagesx, im= agesy, imagecolorstotal.

I believe PHP should= only offer required building blocks and leave to the libraries the impleme= ntation of more structured functionality. My proposal is a completely diffe= rent function called imagematch() that solves the exact problem of the pixe= l-by-pixel matching, with the added value of optionally matching portions o= f the images, using the following signature:

funct= ion imagematch(GdImage $image1, GdImage $image2, int $x1 =3D 0, int $y1 =3D= 0, int $x2 =3D 0, int $y2 =3D 0, ?int $width =3D null, ?int $height =3D nu= ll): bool {}

I already drafted PR #14914 [3] with = the first two parameters. There is not an equivalent libgd implementation, = so the implementation is entirely on the php side, but as you can see it= 9;s quite trivial. Even with the extended functionality of matching portion= s of the images it would be just a few extra lines of code, so not a big ma= intenance burden.

If an RFC is required, I'm h= appy to redact it after the initial feedback round.

[1] https://github.= com/php/php-src/pull/14877

--000000000000606bed061cf57bef--