Skip to content

Commit 643a77d

Browse files
committed
Port fix for libgd bug 276
The issue that BMP RLE occasionally swallowed some pixels[1] had been fixed long ago in libgd, but apparently it has been overlooked to port it to our bundled libgd. We also introduce the test helper `test_image_equals_image()` which compares in-memory images for equality. [1] <libgd/libgd#276> Closes GH-17250.
1 parent a24eada commit 643a77d

File tree

4 files changed

+50
-10
lines changed

4 files changed

+50
-10
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ PHP NEWS
4141
- GD:
4242
. Fixed bug GH-16255 (Unexpected nan value in ext/gd/libgd/gd_filter.c).
4343
(nielsdos, cmb)
44+
. Ported fix for libgd bug 276 (Sometimes pixels are missing when storing
45+
images as BMPs). (cmb)
4446

4547
- Gettext:
4648
. Fixed bug GH-17202 (Segmentation fault ext/gettext/gettext.c

ext/gd/libgd/gd_bmp.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,7 @@ static int compress_row(unsigned char *row, int length)
350350
}
351351

352352
if (compressed_run) {
353-
if (rle_type == BMP_RLE_TYPE_RLE) {
354-
compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row);
355-
}
353+
compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row);
356354
}
357355

358356
gdFree(uncompressed_start);

ext/gd/tests/func.inc

+21-7
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,8 @@ function get_libxpm_version()
7070
* message is printed, and the actual file is stored right beside the temporary
7171
* .php test file with the extension .out.png, to be able to manually inspect
7272
* the result.
73-
*
74-
* @param string $filename
75-
* @param resource $actual
76-
* @return void
7773
*/
78-
function test_image_equals_file($filename, $actual)
74+
function test_image_equals_file(string $filename, GdImage $actual): void
7975
{
8076
if (!file_exists($filename)) {
8177
echo "The expected image does not exist.\n";
@@ -85,13 +81,29 @@ function test_image_equals_file($filename, $actual)
8581
$actual = test_to_truecolor($actual);
8682
$expected = imagecreatefrompng($filename);
8783
$expected = test_to_truecolor($expected);
84+
test_image_equals_image($expected, $actual, true);
85+
}
86+
87+
/**
88+
* Tests that an in-memory image equals another in-memory image.
89+
*
90+
* It checks for equal image sizes, and whether any pixels are different.
91+
* The textual result is printed, so the EXPECT section should contain the line
92+
* "The images are equal."
93+
*
94+
* If the images are not equal, a diagnostic message is printed.
95+
*/
96+
function test_image_equals_image(GdImage $expected, GdImage $actual, bool $save_actual = false): void
97+
{
8898
$exp_x = imagesx($expected);
8999
$exp_y = imagesy($expected);
90100
$act_x = imagesx($actual);
91101
$act_y = imagesy($actual);
92102
if ($exp_x != $act_x || $exp_y != $act_y) {
93103
echo "The image size differs: expected {$exp_x}x{$exp_y}, got {$act_x}x{$act_y}.\n";
94-
save_actual_image($actual);
104+
if ($save_actual) {
105+
save_actual_image($actual);
106+
}
95107
return;
96108
}
97109
$pixels_changed = 0;
@@ -108,7 +120,9 @@ function test_image_equals_file($filename, $actual)
108120
echo "The images are equal.\n";
109121
} else {
110122
echo "The images differ in {$pixels_changed} pixels.\n";
111-
save_actual_image($actual);
123+
if ($save_actual) {
124+
save_actual_image($actual);
125+
}
112126
}
113127
}
114128

ext/gd/tests/gd276.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
libgd bug 276 (Sometimes pixels are missing when storing images as BMPs)
3+
--EXTENSIONS--
4+
gd
5+
--FILE--
6+
<?php
7+
require __DIR__ . "/func.inc";
8+
9+
$orig = imagecreate(10, 10);
10+
imagecolorallocate($orig, 0, 0, 0);
11+
$white = imagecolorallocate($orig, 255, 255, 255);
12+
imageline($orig, 0, 0, 99, 99, $white);
13+
14+
$filename = __DIR__ . "/gd276.bmp";
15+
imagebmp($orig, $filename, true);
16+
$saved = imagecreatefrombmp($filename);
17+
var_dump($saved !== false);
18+
test_image_equals_image($orig, $saved);
19+
?>
20+
--EXPECT--
21+
bool(true)
22+
The images are equal.
23+
--CLEAN--
24+
<?php
25+
@unlink(__DIR__ . "/gd276.bmp");
26+
?>

0 commit comments

Comments
 (0)