#1 2012-02-14 10:47:17

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Access violation drawing metafile with bitmap

I got a AV when I trying to create a PDF, drawing a Metafile that contains a bitmap image.

SynCommons: 1.15
SynPdf........: 1.16

Error stack trace:

[007B3440] SynCommons.SubHash (Line 13358, "JJWCommon\Third Part\pdf\SynCommons.pas" + 20) + $A
[007B3458] SynCommons.Hash32 (Line 13365, "JJWCommon\Third Part\pdf\SynCommons.pas" + 0) + $0
[007E931C] SynPdf.DoHash (Line 5018, "JJWCommon\Third Part\pdf\SynPdf.pas" + 1) + $4
[007E9472] SynPdf.TPdfDocument.CreateOrGetImage (Line 5042, "JJWCommon\Third Part\pdf\SynPdf.pas" + 19) + $D
[007EF7A6] SynPdf.TPdfEnum.DrawBitmap (Line 7596, "JJWCommon\Third Part\pdf\SynPdf.pas" + 16) + $11
[007EF470] SynPdf.EnumEMFFunc (Line 7494, "JJWCommon\Third Part\pdf\SynPdf.pas" + 215) + $30
[007EF586] SynPdf.TPdfCanvas.RenderMetaFile (Line 7531, "JJWCommon\Third Part\pdf\SynPdf.pas" + 18) + $1F


Code:

    with TPdfDocumentGDI.Create do
      try
        //evita o problema de não rendenizar o texto corretamente
        UseUniscribe := True;

        CompressionMethod := cmFlateDecode;
        ScreenLogPixels := 72;

        NewDoc;
        with AddPage do
          Canvas.RenderMetaFile(myTMetafileInstance, 1, MARGIN, -MARGIN, False, 0, 0);
      finally
        Free;
      end;

If you need the source metafile, send me a private message with your email address, and I will send you it.

Thanks.

Last edited by betoneto.tbo (2012-02-14 10:52:02)

Offline

#2 2012-02-14 11:25:58

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Re: Access violation drawing metafile with bitmap

I tried with the trunk version (1.16), I defined USEPACKAGES in Synopse.inc (because I'm using the SynPdf in a runtime package).

I got another AV.....

[007B47CA] SynCommons.Hash32 (Line 13908, "JJWCommon\Third Part\pdf\SynCommons.pas" + 35) + $0
[007EB080] SynPdf.DoHash (Line 5027, "JJWCommon\Third Part\pdf\SynPdf.pas" + 1) + $4
[007EB1D6] SynPdf.TPdfDocument.CreateOrGetImage (Line 5051, "JJWCommon\Third Part\pdf\SynPdf.pas" + 19) + $D
[007F150A] SynPdf.TPdfEnum.DrawBitmap (Line 7603, "JJWCommon\Third Part\pdf\SynPdf.pas" + 16) + $11
[007F11D1] SynPdf.EnumEMFFunc (Line 7501, "JJWCommon\Third Part\pdf\SynPdf.pas" + 216) + $30
[007F12EA] SynPdf.TPdfCanvas.RenderMetaFile (Line 7538, "JJWCommon\Third Part\pdf\SynPdf.pas" + 18) + $1F


At the first post, I was using PUREPASCAL define...

Offline

#3 2012-02-14 12:09:48

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Re: Access violation drawing metafile with bitmap

Take a look on the algorithm of (SynCommons.pas 1.16)


function SubHash(P: PCardinalArray; L: integer): cardinal;

// from line = 13838
// L = 3072

1:  for i := 1 to L shr 4 do begin // 16 bytes (4 DWORD) by loop - aligned read
      inc(s1,P^[0]);
      inc(s2,s1);
      inc(s1,P^[1]);
      inc(s2,s1);
      inc(s1,P^[2]);
      inc(s2,s1);
      inc(s1,P^[3]);
      inc(s2,s1);
2:    inc(PtrUInt(P),16);
    end;
    for i := 1 to (L shr 2)and 3 do begin // 4 bytes (DWORD) by loop
      inc(s1,P^[0]);
      inc(s2,s1);
      inc(PtrUInt(P),4);
    end;
3:    inc(s1,P^[0] and Mask[L and 3]);      // remaining 0..3 bytes
    inc(s2,s1);
    result := s1 xor (s2 shl 16);


1 -> ((L = 3072) shr 4) = 192
2 -> 192 * 16 = 3072 (END OF CARDINAL ARRAY)
3 -> (THERE ISN'T 4 REMAINING BYTES, NOW AV!)

Offline

#4 2012-02-14 12:42:17

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Re: Access violation drawing metafile with bitmap

Here is the example: http://www.4shared.com/zip/eLNLqKEZ/SynPDF_AV.html
Zip password is: synpdfav

Offline

#5 2012-02-14 12:58:32

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Re: Access violation drawing metafile with bitmap

I got a WORKAROUND:

  // setting on TPdfDocumentGDI
  pdf.ForceNoBitmapReuse := True;

Offline

#6 2012-02-14 13:14:13

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

Re: Access violation drawing metafile with bitmap

There was indeed an issue in Hash32() implementation (potential GPF when reading ahead by DWORD - get rid of unnecessary asm optimization).
sad
See http://synopse.info/fossil/info/241337a58c

I think it will fix your issue, without setting ForceNoBitmapReuse := True, which may create potentially much bigger PDF.

Thanks for the report.
smile

Offline

#7 2012-02-14 13:55:17

betoneto.tbo
Member
From: Brasil
Registered: 2011-05-10
Posts: 29

Re: Access violation drawing metafile with bitmap

"Thanks" you man, nice support!

Now I'm able to inactive PUREPASCAL define, and all works fine!!!

.... BUT using PUREPASCAL another AV occurs...

Version: 1.16 (trunk)

[005EC479] SynPdf.HashOf (Line 4994, "JJWCommon\Third Part\pdf\SynPdf.pas" + 3) + $C
[005EC4CB] SynPdf.DoHash (Line 5028, "JJWCommon\Third Part\pdf\SynPdf.pas" + 2) + $4
[005EC616] SynPdf.TPdfDocument.CreateOrGetImage (Line 5051, "JJWCommon\Third Part\pdf\SynPdf.pas" + 19) + $D
[005F294A] SynPdf.TPdfEnum.DrawBitmap (Line 7603, "JJWCommon\Third Part\pdf\SynPdf.pas" + 16) + $11
[005F2611] SynPdf.EnumEMFFunc (Line 7501, "JJWCommon\Third Part\pdf\SynPdf.pas" + 216) + $30
[005F272A] SynPdf.TPdfCanvas.RenderMetaFile (Line 7538, "JJWCommon\Third Part\pdf\SynPdf.pas" + 18) + $1F

Offline

#8 2012-02-14 15:58:03

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

Re: Access violation drawing metafile with bitmap

You are right also this time.

There was an issue in the PUREPASCAL version of SynPdf.HashOf()

See http://synopse.info/fossil/info/2d603b6027

Thanks for the report.

Offline

Board footer

Powered by FluxBB