#1 2018-01-18 07:28:02

Marsh
Member
Registered: 2015-02-21
Posts: 6

Bitmap with height 1 pixel results in a corrupted file

Hi,

after having used SynPDF for years without any issues, I stumbled upon a small problem today which leads to corrupted PDFs. I found out what's happening, but not sure about the proper solution.

So basically, my application tried to create a pdf that contains a Bitmap with a height of 1 pixel. In the procedure TPdfEnum.DrawBitmap, the bitmap size R is rescaled to variable Box in the function BoxI/RectI. But this rescaling results in a height of 0, which then leads to a corrupted PDF file (often, the PDF ends up corrupt, and if not, it usually does not continue drawing any elements that were added after the bitmap).

1. Why are both the right and bottom coordinates for variable Box shifted by -1 in function RectI?
2. Maybe there should be some error handling when height or width of the variable Box is 0, or the bitmap should not be drawn at all?

See the code section below. variable ClipRc is checked if it's actually a valid rectangle, but variable Box is not.

    // draw the bitmap on the PDF canvas
    with Canvas do begin
      R := Rect(xd, yd, wd+xd, hd+yd);
      NormalizeRect(R);
      Box := BoxI(R,true);
      ClipRc := GetClipRect;
      if (ClipRc.Width>0) and (ClipRc.Height>0) then
        Doc.CreateOrGetImage(B, @Box, @ClipRc) else // use cliping
        Doc.CreateOrGetImage(B, @Box, nil);
      // Doc.CreateOrGetImage() will reuse any matching TPdfImage
      // don't send bmi and bits parameters here, because of StretchDIBits above
    end;

Offline

#2 2018-01-18 09:45:44

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,603
Website

Re: Bitmap with height 1 pixel results in a corrupted file

Marsh wrote:

1. Why are both the right and bottom coordinates for variable Box shifted by -1 in function RectI?

AFAIR it is because PDF boxes coordinates expect that.

Marsh wrote:

2. Maybe there should be some error handling when height or width of the variable Box is 0, or the bitmap should not be drawn at all?

I guess the bitmap should not be drawn at all... what do you think?

Offline

#3 2018-01-23 09:48:15

Marsh
Member
Registered: 2015-02-21
Posts: 6

Re: Bitmap with height 1 pixel results in a corrupted file

ab wrote:

I guess the bitmap should not be drawn at all... what do you think?

In my case, I do have such a bitmap that contains information I need on the pdf (might seem silly, but that's how it is, and I have to work with that). So just not drawing is not an option for me.

ab wrote:

AFAIR it is because PDF boxes coordinates expect that.

I'll try to look further into that later this week, it seems a bit peculiar.

Offline

#4 2018-03-22 17:06:14

MtwStark
Member
From: Italy
Registered: 2016-01-05
Posts: 27

Re: Bitmap with height 1 pixel results in a corrupted file

Hi Marsh,
the problem is not the BoxI function, but the starting rect R.

It should be 1px bigger than bitmap because the BoxI expect a rect with right and bottom border excluded.

change:

R := Rect(xd, yd, wd + xd, hd + yd);

in:

R := Rect(xd, yd, wd + xd + 1, hd + yd + 1);

With images larger or higher than 1px, you do not see the problem because the image is not "truncated" for the missing pixel but it is painted a (very) little stretched

If you try placing two normal bitmaps one over the other,
you should notice that with inflated rect, the draw will reach the correct right-bottom corner.

If you prefer not to modify existing behaviour for all pictures you can simply use:

if wd=1 then Inc(wd);
if hd=1 then Inc(hd);
R := Rect(xd, yd, wd + xd, hd + yd);

have a nice day

Last edited by MtwStark (2018-03-22 17:42:57)

Offline

Board footer

Powered by FluxBB