Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: TImage.paint access violation when loading specific .jpg



Permlink Replies: 11 - Last Post: Dec 8, 2016 10:46 AM Last Post By: Carl-Henrik Nil... Threads: [ Previous | Next ]
Gerrit Beuze

Posts: 70
Registered: 10/16/00
TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2016 8:11 AM
Hi all,

I'm using a TImage in a Delphi 2010 VCL app to display a preview for a user picked image.
I have one report for a specific .jpeg image that causes TImage to crash.
I tried to reproduce it: using Delphi 2010 created a new VCL application,
in the form designer add a TImage and load the image from the link below.
This will also crash inside th eDelphi IDE.

When running in the debugger I see that the problem is caused in
when accessing "inherited Canvas", the debug evaluator also shows a Delphi exception
when trying to evaluate that expression

procedure TImage.Paint;
[...]
begin
[...]

Save := FDrawing;
FDrawing := True;
try
if (csGlassPaint in ControlState) and (Picture.Graphic <> nil) and
not Picture.Graphic.SupportsPartialTransparency then
DoBufferedPaint(inherited Canvas)
else
// this call crashes: "with inherited Canvas"
with inherited Canvas do
StretchDraw(DestRect, Picture.Graphic);
finally
FDrawing := Save;
end;

end;

This image that causes the problem can be downloaded from
http://modelmakertools.com/betas/invalid-image-tasks.jpg

It is large, but I can load much larger .jpgs withour problems.

Any work arounds for this?

Gerrit Beuze
ModelMaker Tools

Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2016 10:41 AM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Gerrit,

| withour[t]

--

Q -- XanaNews 1.19.1.372 - 2016-12-01 10:41:11
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2016 10:44 AM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Gerrit wrote:

When running in the debugger I see that the problem is caused in
when accessing "inherited Canvas"

What is the actual error message? Simply accessing the inherited Canvas
property itself cannot crash. The crash is more likely happening during
the actual drawing in TCanvas.StretchDraw().

the debug evaluator also shows a Delphi exception when trying
to evaluate that expression

Which expression exactly? What is the actual error message?

This image that causes the problem can be downloaded from
http://modelmakertools.com/betas/invalid-image-tasks.jpg

That image works fine as-is for me in XE2. Maybe the JPG library in D2010
is buggy, or perhaps the JPG is corrupted in some way that it can't handle.

--
Remy Lebeau (TeamB)
Carl-Henrik Nil...

Posts: 53
Registered: 3/26/02
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 1, 2016 12:30 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
That image works fine as-is for me in XE2. Maybe the JPG library in D2010
is buggy, or perhaps the JPG is corrupted in some way that it can't handle.
I can confirm that it causes an access violation in an app built with D2010. Works fine in XE5.
So there is a problem with the the 2010 library. Haven't tried to locate the problem though.
--
C-H
Gerrit Beuze

Posts: 70
Registered: 10/16/00
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2016 1:51 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
When running in the debugger I see that the problem is caused in
when accessing "inherited Canvas"
What is the actual error message?

Access Violation ...

Simply accessing the inherited
Canvas property itself cannot crash.

It does.

The crash is more likely
happening during the actual drawing in TCanvas.StretchDraw().

That's in the local procedure, which is not called.


the debug evaluator also shows a Delphi exception when trying
to evaluate that expression
Which expression exactly?

"inherited Canvas"

What is the actual error message?

This image that causes the problem can be downloaded from
http://modelmakertools.com/betas/invalid-image-tasks.jpg

That image works fine as-is for me in XE2. Maybe the JPG library in
D2010 is buggy, or perhaps the JPG is corrupted in some way that it
can't handle.

The image itself is OK, it can be opened with other software (and as
Carl-Henrik tested: can be opened with XE5.

It seems the question is: what bug was solved that makes it work in XE5
but not in D2010? Does not need to be in TImage. I compared the source
for the paint / draw routines in D2010 source and Delphi 10 Berlin and
see no differences there.

Gerrit Beuze

Carl-Henrik Nil...

Posts: 53
Registered: 3/26/02
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2016 3:58 AM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Gerrit Beuze wrote:
It seems the question is: what bug was solved that makes it work in XE5
but not in D2010? Does not need to be in TImage. I compared the source
for the paint / draw routines in D2010 source and Delphi 10 Berlin and
see no differences there.
The problem is in the Jpeg library. There are a lot of changes between the two versions.
--
C-H
Carl-Henrik Nil...

Posts: 53
Registered: 3/26/02
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2016 5:19 AM   in response to: Carl-Henrik Nil... in response to: Carl-Henrik Nil...
Carl-Henrik Nilsson wrote:
The problem is in the Jpeg library. There are a lot of changes between the two versions.
If you have to use D2010 you can get around the problem by removing all Jpeg unit references from uses,
and instead register TWICImage for Jpeg images.

For example:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  TForm1: TMainForm;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute(Handle) then
    Image1.Picture.LoadFromFile(OpenDialog1.FileName);
end;
 
initialization
  TPicture.RegisterFileFormat ('jpg', 'JPEG Image', TWICImage);
  TPicture.RegisterFileFormat ('jpeg', 'JPEG Image', TWICImage);
 
//  TWICImage also works for these formats:
//  TPicture.RegisterFileFormat ('png', 'PNG Image', TWICImage);
//  TPicture.RegisterFileFormat ('bmp', 'Bitmap Image', TWICImage);
//  TPicture.RegisterFileFormat ('gif', 'GIF Image', TWICImage);
//  TPicture.RegisterFileFormat ('ico', 'Icon Image', TWICImage);
end. 

--
C-H

Gerrit Beuze

Posts: 70
Registered: 10/16/00
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 2, 2016 10:10 AM   in response to: Carl-Henrik Nil... in response to: Carl-Henrik Nil...
The problem is in the Jpeg library. There are a lot of changes between the two versions.
If you have to use D2010 you can get around the problem by removing all Jpeg unit references from uses,
and instead register TWICImage for Jpeg images.

Thanks, I'll give that a trye,

Gerrit Beuze
ModelMaker Tools

Gerrit Beuze

Posts: 70
Registered: 10/16/00
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 8, 2016 1:41 AM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Hi,

I copied the jpeg image .pas and .obj files from the Delphi 10.1 Berlin win32 source over
to the project's directory. Including that unit makes it open the CYML jpg. Needed to fix
some compile errors and merging some missing functions from the D2010 jpeg.pas source

Should this be a safe thing to do?

Gerrit Beuze


The problem is in the Jpeg library. There are a lot of changes between the two versions.
If you have to use D2010 you can get around the problem by removing all Jpeg unit references from uses,
and instead register TWICImage for Jpeg images.

Thanks, I'll give that a trye,

Gerrit Beuze
ModelMaker Tools

Carl-Henrik Nil...

Posts: 53
Registered: 3/26/02
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 8, 2016 10:46 AM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Gerrit Beuze wrote:
I copied the jpeg image .pas and .obj files from the Delphi 10.1 Berlin win32 source over
to the project's directory. Including that unit makes it open the CYML jpg. Needed to fix
some compile errors and merging some missing functions from the D2010 jpeg.pas source

Should this be a safe thing to do?

Well, it's safe if you do it right is all I can say <g>.

--
C-H

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 3, 2016 1:55 PM   in response to: Gerrit Beuze in response to: Gerrit Beuze
Gerrit wrote:

What is the actual error message?
Access Violation ...

Next time someone asks you for an error message, please provide the COMPLETE
error message. There is more information in an "Access Violation" error
message.

Simply accessing the inherited Canvas property itself cannot crash.

It does.

The inherited Canvas property getter ensures the Picture.Graphic is a TBitmap
(since that is the only graphic class that has a TCanvas for drawing), so
the ONLY way I cansee accessing the inherited Canvas can crash is if the
Picture property is pointing as an invalid TPicture object, or its Graphic
property is pointing at an invalid TBitmap object. You need to debug the
code to find out.

The image itself is OK, it can be opened with other software (and as
Carl-Henrik tested: can be opened with XE5.

And as I said, in XE2.

It seems the question is: what bug was solved that makes it work in
XE5 but not in D2010? Does not need to be in TImage.

The problem is not in TImage, but in the underlying Jpeg library that Delphi
uses.

I compared the source for the paint / draw routines in D2010 source
and Delphi 10 Berlin and see no differences there.

Of course, because you are looking at the TImage source. Look at the TJpegImage
source in Vcl.Imaging.Jpeg.pas instead, and also the C library source in
the "$(BDS)\source\vcl\jpg\src" folder.

--
Remy Lebeau (TeamB)
Carl-Henrik Nil...

Posts: 53
Registered: 3/26/02
Re: TImage.paint access violation when loading specific .jpg
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 4, 2016 1:18 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
What is the actual error message?

I've taken a closer look at the AV, and it happens on this line of the GetBitmap method of Jpeg.pas:
        // final image pass for progressive, first and only pass for baseline
        while (jc.d.output_scanline < jc.d.output_height) do
        begin
          LinesRead := jpeg_read_scanlines(jc.d, @DestScanline, LinesPerCall); //<---------AV on first pass


The ColorSpace of the picture is CMYK, which isn't supported by the D2010 Jpeg.
--
C-H
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02