From d692b02b7c670e8ef38c967c78436942a15111e3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 24 Dec 2024 15:42:18 +0100 Subject: [PATCH 1/2] Port "fix BMP header size" Cf. . --- ext/gd/libgd/gd_bmp.c | 16 ++++++++-------- ext/gd/tests/bmp_size.phpt | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 ext/gd/tests/bmp_size.phpt diff --git a/ext/gd/libgd/gd_bmp.c b/ext/gd/libgd/gd_bmp.c index a80904a62914d..e704ba552bbba 100644 --- a/ext/gd/libgd/gd_bmp.c +++ b/ext/gd/libgd/gd_bmp.c @@ -129,8 +129,14 @@ void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) } } + /* The line must be divisible by 4, else it's padded with NULLs */ + padding = ((int)(im->trueColor ? 3 : 1) * im->sx) % 4; + if (padding) { + padding = 4 - padding; + } + /* bitmap header + info header + data */ - total_size = 14 + info_size + bitmap_size; + total_size = 14 + info_size + bitmap_size + padding * im->sy; /* write bmp header info */ gdPutBuf("BM", 2, out); @@ -146,18 +152,12 @@ void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) gdBMPPutWord(out, 1); /* colour planes */ gdBMPPutWord(out, (im->trueColor ? 24 : 8)); /* bit count */ gdBMPPutInt(out, (compression ? BMP_BI_RLE8 : BMP_BI_RGB)); /* compression */ - gdBMPPutInt(out, bitmap_size); /* image size */ + gdBMPPutInt(out, bitmap_size + padding * im->sy); /* image size */ gdBMPPutInt(out, 0); /* H resolution */ gdBMPPutInt(out, 0); /* V ressolution */ gdBMPPutInt(out, im->colorsTotal); /* colours used */ gdBMPPutInt(out, 0); /* important colours */ - /* The line must be divisible by 4, else it's padded with NULLs */ - padding = ((int)(im->trueColor ? 3 : 1) * im->sx) % 4; - if (padding) { - padding = 4 - padding; - } - /* 8-bit colours */ if (!im->trueColor) { for(i = 0; i< im->colorsTotal; ++i) { diff --git a/ext/gd/tests/bmp_size.phpt b/ext/gd/tests/bmp_size.phpt new file mode 100644 index 0000000000000..94ecb50843746 --- /dev/null +++ b/ext/gd/tests/bmp_size.phpt @@ -0,0 +1,17 @@ +--TEST-- +bfSize field of bitmap header matches actual file size +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +string(2) "BM" +bool(true) From 6b1dbf82bd1464c977d483e67f870ebf63169495 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 25 Dec 2024 17:09:51 +0100 Subject: [PATCH 2/2] Fix size calculation We need to cater to compressed images, too. We also augment the test case to check the `biSizeImage` field, and also do the checks for compressed images. --- ext/gd/libgd/gd_bmp.c | 4 ++-- ext/gd/tests/bmp_size.phpt | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ext/gd/libgd/gd_bmp.c b/ext/gd/libgd/gd_bmp.c index e704ba552bbba..321f6ee45bda7 100644 --- a/ext/gd/libgd/gd_bmp.c +++ b/ext/gd/libgd/gd_bmp.c @@ -136,11 +136,11 @@ void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) } /* bitmap header + info header + data */ - total_size = 14 + info_size + bitmap_size + padding * im->sy; + total_size = 14 + info_size + bitmap_size; /* write bmp header info */ gdPutBuf("BM", 2, out); - gdBMPPutInt(out, total_size); + gdBMPPutInt(out, total_size + padding * im->sy); gdBMPPutWord(out, 0); gdBMPPutWord(out, 0); gdBMPPutInt(out, 14 + info_size); diff --git a/ext/gd/tests/bmp_size.phpt b/ext/gd/tests/bmp_size.phpt index 94ecb50843746..e123f85922135 100644 --- a/ext/gd/tests/bmp_size.phpt +++ b/ext/gd/tests/bmp_size.phpt @@ -1,17 +1,37 @@ --TEST-- -bfSize field of bitmap header matches actual file size +bfSize and biSizeImage fields of bitmap header match actual file size --EXTENSIONS-- gd --FILE-- --EXPECT-- string(2) "BM" bool(true) +bool(true) +string(2) "BM" +bool(true) +bool(true)