ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Access Violation in ImageEnMView.GetImageToStream
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 01 2016 :  14:07:54  Show Profile  Reply
Hi,

Odd one this.

I've implemented a form specifically for adding multiple images from a file to the database. Users browse using an ImageEnFolderMView & double click to add the image to an ImageEnMView, using the following:


    ImageEnMView.LoadFromFile(ImageEnFolderMView.SelectedFilename);


Finally users hit OK and the images in the ImageEnMView are added to the database, by using MView.ImageCount to iteratively call MView.GetImageToStream(idx, stream. ioJPEG).

At the third image in the MView (idx = 2) the GetImageToStream function is causing an Access Violation. Doesn't matter which image it is - so there isn't a specific "problem image". I've tried a variety of images, in a variety of orders.

I've traced into iemview.pas and the offending line is in


procedure TImageEnMView.GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: TIOFileType);
var
  bmp: TIEBitmap;
begin
  fImageEnIO.Params.Assign( GetImageEnMIO.Params[idx] );    /// <<--- Access Violation here
  bmp := GetTIEBitmap(idx);
  try
    fImageEnIO.AttachedIEBitmap := bmp;
    fImageEnIO.SaveToStream(Stream, ImageFormat);
  finally
    ReleaseBitmap(idx, false);
  end;
end;


On further inspection the fImageEnIO.Params value is "inaccessible" & thus will probably be the cause of the A/V, so I stepped into the TImageEnIO.GetParams function:


  if assigned( fIEBitmap ) and fIEBitmap.ParamsEnabled then
    Result := fIEBitmap.Params
  else
    Result := fParams;


In the above code, assigned( fIEBitmap ) returns True, but the object doesn't seem properly formed (if you get my meaning). I.e., the fIEBitmap.Params is "inaccessible value" & the fAccess field of fIEBitmap is "out of bound (7)". See image:



I've been unable to replicate this in the FolderMView demo - but that's obviously a different scenario to the more complex application.

Below is the bug report from MadExcept if it helps (suspect not).

For clarity here's a little more about the code. The TfrmCaptureFileImage is exposing methods to provide access to the images in the MView from the calling form (frmPatientCaseDefault), e.g.


function TfrmCaptureFileImage.GetImageStream(const aIndex: Integer; var aStream: TMemoryStream; const aFileFormat: Integer): Boolean;
begin
  aStream.Position := 0;
  MView.GetImageToStream(aIndex, aStream, aFileFormat);
end;


The calling code is simply:


  for I := 0 to intfImaging.ImageCount-1 do   // intfImaging is an interface to TfrmCaptureFileImage
  begin
    aJpegStream := TMemoryStream.Create;
    try
      intfImaging.GetImageStream(I, aJpegStream, ioJPEG);
      aJpegStream.Position := 0;
      dm.AddImageFromStream(aJpegStream, aFormatModule, '');
    finally
      aJpegStream.Free;
    end;
    dm.SaveData;
    UpdateProgress(Succ(I));
  end;



Thanks in advance,
Stuart

BugReport:

exception class : EAccessViolation
exception message : Access violation at address 01F75B53 in module 'aquilacrs.exe'. Read of address 80808088.


main thread ($380):
01f75b53 +01f aquilacrs.exe iexBitmaps                        TIOParams.Assign
01d97273 +033 aquilacrs.exe iemview                12160   +1 TImageEnMView.GetImageToStream
02bc2d26 +0a6 aquilacrs.exe frmCaptureFileImage1     264  +10 TfrmCaptureFileImage.GetImageStream
01faec76 +1d2 aquilacrs.exe frmPatientCaseDefaultU  1877  +40 TfrmPatientCaseDefault.AcquireImage
01fae9f3 +027 aquilacrs.exe frmPatientCaseDefaultU  1784   +3 TfrmPatientCaseDefault.actImportImageFromFileExecute
004e1e17 +00f aquilacrs.exe System.Classes         16674   +3 TBasicAction.Execute
0054b76e +086 aquilacrs.exe Vcl.ActnList             260  +19 TCustomAction.Execute
004e1c83 +013 aquilacrs.exe System.Classes         16585   +2 TBasicActionLink.Execute
0117b9d2 +052 aquilacrs.exe dxBar                             TdxBarItem.DoClick
0117b94f +03b aquilacrs.exe dxBar                             TdxBarItem.DirectClick
01175a3f +11f aquilacrs.exe dxBar                             TdxBarItemControl.ControlUnclick
01179387 +077 aquilacrs.exe dxBar                             TdxBarButtonControl.ControlUnclick
011a81a8 +0e0 aquilacrs.exe dxBar                             TCustomdxBarControl.DoLButtonUp
011a6c04 +028 aquilacrs.exe dxBar                             TCustomdxBarControl.WMLButtonUp
0056ae72 +2be aquilacrs.exe Vcl.Controls            7313  +91 TControl.WndProc
0056f9bd +5e9 aquilacrs.exe Vcl.Controls           10143 +158 TWinControl.WndProc
011a76ff +1bb aquilacrs.exe dxBar                             TCustomdxBarControl.WndProc
0056efdc +02c aquilacrs.exe Vcl.Controls            9850   +3 TWinControl.MainWndProc
004e2b74 +014 aquilacrs.exe System.Classes         17178   +8 StdWndProc
753ea6db +00b user32.dll                                      DispatchMessageW
0067f90b +0f3 aquilacrs.exe Vcl.Forms              10534  +23 TApplication.ProcessMessage
0067f94e +00a aquilacrs.exe Vcl.Forms              10564   +1 TApplication.HandleMessage
0067fc81 +0c9 aquilacrs.exe Vcl.Forms              10702  +26 TApplication.Run
02c327cd +06d aquilacrs.exe aquilacrs                386  +10 initialization
77197c02 +022 KERNEL32.DLL                                    BaseThreadInitThunk



Stuart Clennett
Delphi Berlin 10.1

xequte

38127 Posts

Posted - Nov 03 2016 :  05:04:30  Show Profile  Reply
Hi Stuart

That's an odd one. Are you sure that memory is not being trashed somewhere?

Is it possible to create a simple demo that reproduces this issue?



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Gubben

Norway
11 Posts

Posted - Nov 03 2016 :  15:17:19  Show Profile  Reply
I have the exact same issue, using Tiff.

It's random, can work for hours with no problem. Suddenly it's every 5 minutes.

Ole
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 03 2016 :  15:24:08  Show Profile  Reply
Hi Nigel,

I'll double check - but the code is v.simple and a copy/paste of code I have working in another, similar, form. There are two forms to support image acquisition - one for the filesystem (which Im having problems with) and one for WIA/WPD/Twain acquision sources.

The code that calls the GetImageToStream is indentical between the two forms (so much that I was considering refactoring into a base form with two descendant forms).

I'll see if I can reproduce in a simpler demo app when I get 5 mins.

For now I have worked around it by modifying iemview.pas, but obviously need a better solution:


procedure TImageEnMView.GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: TIOFileType);
var
  bmp: TIEBitmap;
begin
  try
    fImageEnIO.Params.Assign( GetImageEnMIO.Params[idx] );  // .params could in invalid & cause access violation
  except
    fImageEnIO.fParams.Assign( GetImageEnMIO.Params[idx] ); // fall back on fParams - not sure what side effect this will have re: EXIF
  end
  bmp := GetTIEBitmap(idx);
  try
    fImageEnIO.AttachedIEBitmap := bmp;
    fImageEnIO.SaveToStream(Stream, ImageFormat);
  finally
    ReleaseBitmap(idx, false);
  end;
end;



Cheers



Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 08 2016 :  14:20:14  Show Profile  Reply
Hi Nigel,

Sorry, I've been unable to replicate this in a test app. I've replicated the calling code and even used the original forms -- but no deal. In the original app I've stripped down the code such that no database stuff is happening & we're just reading the image stream and ignoring it - but still the problem persists in the main app, but does not occur in the demo app.

I've (accidentally) discovered a workaround though as follows:


function TfrmCaptureFileImage.GetImageStream(const aIndex: Integer; var aStream: TMemoryStream; const aFileFormat: Integer): Boolean;
begin
  MView.GetTIEBitmap(aIndex);  // adding this as it seems to prevent Access Violation in the GetImageToStream... ?
  aStream.Position := 0;
  if aFileFormat = ioUnknown then
  begin
    if (MView.MIO.Params[aindex].FileType  in IMAGE_FORMATS_TO_FORCE_TO_JPEG) then
      MView.GetImageToStream(aIndex, aStream, ioJPEG)
    else
      MView.GetImageToStream(aIndex, aStream, MView.MIO.Params[aindex].FileType)
  end else
    MView.GetImageToStream(aIndex, aStream, aFileFormat);
end;


This function is from the form that allows the user to import multiple files at once. Once the form has been shown and the user hits OK, this method is called repeatedly by the calling form to import each image in the MView to the database.

Adding MView.GetTIEBitmap(aIndex) before the call to GetImageToStream - cures the A/V.

I'd appreciate any comment or insight you might have - 'cause I've been going around in circles for 2 days now.

Cheers,
Stu

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

xequte

38127 Posts

Posted - Nov 11 2016 :  16:17:33  Show Profile  Reply
Hi Stu

If calling MView.GetTIEBitmap(aIndex); fixes it, then that would imply that the image is not yet available (i.e. loaded). But really, the subsequent calls within ImageEn should deal with that case anyway. So I suspect it is actually some unexpected race condition, which will make it difficult to debug.

Just as a test, how about if you replace:

MView.GetTIEBitmap(aIndex);

With:

MView.ObtainImageNow( aIndex );


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 14 2016 :  14:14:30  Show Profile  Reply
Hi Nigel,

Yes, using ObtainImageNow(aIndex) also prevents the access violation from happening.

Thanks,

Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

xequte

38127 Posts

Posted - Nov 14 2016 :  14:45:17  Show Profile  Reply
Hmmm, OK, I will add the extra checking to the code.



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 15 2016 :  05:09:50  Show Profile  Reply
Hi Nigel,

Thanks for staying with this - I'm hesitate to ask you to alter your own software, so I did some further testing.

I released a version of the app to testers with the workaround removed and with instructions to repeat my steps of loading several images through the same utility.

They both report that it's working okay -- i.e. no Access/Violation. They've loaded up 20 images per import - mine fails on the 3rd image usually. They're using exactly the same images I am.

So, environmental differences:

Me: Win8.1, virtual machine (VirtualBox)
Testers: Win10 on bare metal (HP Laptops).

Again, I'm reluctant to add additional code to this library, especially as it seems no one other than me is getting the issue - but I clearly don't know enough about the inner workings of IE to know what this latest test actually may mean.

Cheers
Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

xequte

38127 Posts

Posted - Nov 16 2016 :  04:15:38  Show Profile  Reply
Hi Stuart

ObtainImageNow(aIndex); will not adversely affect performance, so it will be OK to implement.




Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 16 2016 :  04:17:59  Show Profile  Reply
Hi Nigel,

Great thanks very much :)

Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

Gubben

Norway
11 Posts

Posted - Nov 17 2016 :  03:47:56  Show Profile  Reply
I also have this problem.

In my program it fails on the second image, never the first.

I had used my code for several years without problems, the problem appeared when I upgraded to a newer version, don't remember which one now.

I'm very grateful for your investigation, I will try your solution.

Hopfully it will be ok now, this is a serious problem for my users.

Regards,
Ole
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 17 2016 :  04:03:23  Show Profile  Reply
Hi Ole,

Nice to know that someone else is having the same issue, I wondered if it was just me ;-)

Hope the workaround helps you until the next release.

Kind regards
Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

xequte

38127 Posts

Posted - Nov 20 2016 :  14:36:38  Show Profile  Reply
Hi Ole and Stuart

We have located the issue and will have a fix in the next update.



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Nov 21 2016 :  04:30:48  Show Profile  Reply
Thanks Nigel,

Cheers
Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Dec 06 2016 :  05:18:30  Show Profile  Reply
Hi Nigel,

Just got around to upgrading to 6.3.2C. I removed the MView.GetTIEBitmap(aIndex) from my own code, and the Access Violation problem still occurs on the second image when using ImageEnMView.GetImageToStream.

Cheers
Stuart


Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

xequte

38127 Posts

Posted - Dec 06 2016 :  15:46:54  Show Profile  Reply
Hi

V6.3.2B and 6.3.2C include *no* changes to the packages. They only update the ielib libraries.

Please wait for the next version change release (6.3.3, or all going to plan, 7.0.0).



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

stuartclennett@gmail.com

United Kingdom
72 Posts

Posted - Dec 06 2016 :  15:51:28  Show Profile  Reply
Ah I see, no worries.

Many thanks
Stuart

Stuart Clennett
Delphi Berlin 10.1
Go to Top of Page

Ralf

110 Posts

Posted - Mar 15 2017 :  10:33:48  Show Profile  Reply
Hi Nigel,
we have also the same problem and it is a very big problem for us because we have to deliver a Update at the end of this month.
When is the release of 6.3.3 or are ther any units you can send to me before.

Both Idear's doesn't have a positiv result
MView.GetTIEBitmap(aIndex);

MView.ObtainImageNow( aIndex );

We think the error will happen when

function TImageEnIO.GetParams: TIOParams;
begin
if assigned( fIEBitmap ) and fIEBitmap.ParamsEnabled then
Result := fIEBitmap.Params
else
Result := fParams;
end;

the fIEBitmap is filled with an adress but it isn't a image and the result of fIEBitmap.ParamsEnabled is true.

Thanks

Ralf
Go to Top of Page

Ralf

110 Posts

Posted - Mar 16 2017 :  05:53:17  Show Profile  Reply
Hi Nigel,

we had another look on the problem.

we have made in GetImageToStream following change:

procedure TImageEnMView.GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: TIOFileType);
var
  bmp: TIEBitmap;
begin
  bmp := GetTIEBitmap(idx);
  try
    fImageEnIO.AttachedIEBitmap := bmp;
    fImageEnIO.SaveToStream(Stream, ImageFormat);
  finally
    fImageEnIO.AttachedIEBitmap := Nil; <- New Line
    ReleaseBitmap(idx, false);
  end;
end;

The same is in the procedure GetImageToFile. We think that the problem is, that you release the Bitmap but the fImageEnIO.AttachedIEBitmap is still having the reference to the Bitmap.

At the moment we didn't get the Exception again.

Best Regards

Ralf

Go to Top of Page

xequte

38127 Posts

Posted - Mar 19 2017 :  16:02:43  Show Profile  Reply
Hi Ralf

Sorry for your needing to investigate a fixed issue, but we implemented that fix earlier in this beta. We're hoping to have 7.0.0 out in the next few weeks, but you can email for a pre-release if you like.

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: