diff --git a/ext/gd/libgd/gd_bmp.c b/ext/gd/libgd/gd_bmp.c index a80904a62914d..321f6ee45bda7 100644 --- a/ext/gd/libgd/gd_bmp.c +++ b/ext/gd/libgd/gd_bmp.c @@ -129,12 +129,18 @@ 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; /* 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); @@ -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..e123f85922135 --- /dev/null +++ b/ext/gd/tests/bmp_size.phpt @@ -0,0 +1,37 @@ +--TEST-- +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)