Author |
Topic  |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 01 2016 : 14:07:54
|
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
    
38995 Posts |
Posted - Nov 03 2016 : 05:04:30
|
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
|
 |
|
Gubben

Norway
11 Posts |
Posted - Nov 03 2016 : 15:17:19
|
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 |
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 03 2016 : 15:24:08
|
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 |
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 08 2016 : 14:20:14
|
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 |
 |
|
xequte
    
38995 Posts |
Posted - Nov 11 2016 : 16:17:33
|
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
|
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 14 2016 : 14:14:30
|
Hi Nigel,
Yes, using ObtainImageNow(aIndex) also prevents the access violation from happening.
Thanks,
Stuart
Stuart Clennett Delphi Berlin 10.1 |
 |
|
xequte
    
38995 Posts |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 15 2016 : 05:09:50
|
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 |
 |
|
xequte
    
38995 Posts |
Posted - Nov 16 2016 : 04:15:38
|
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
|
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 16 2016 : 04:17:59
|
Hi Nigel,
Great thanks very much :)
Stuart
Stuart Clennett Delphi Berlin 10.1 |
 |
|
Gubben

Norway
11 Posts |
Posted - Nov 17 2016 : 03:47:56
|
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 |
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 17 2016 : 04:03:23
|
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 |
 |
|
xequte
    
38995 Posts |
Posted - Nov 20 2016 : 14:36:38
|
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
|
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Nov 21 2016 : 04:30:48
|
Thanks Nigel,
Cheers Stuart
Stuart Clennett Delphi Berlin 10.1 |
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Dec 06 2016 : 05:18:30
|
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 |
 |
|
xequte
    
38995 Posts |
Posted - Dec 06 2016 : 15:46:54
|
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
|
 |
|
stuartclennett@gmail.com
 
United Kingdom
72 Posts |
Posted - Dec 06 2016 : 15:51:28
|
Ah I see, no worries.
Many thanks Stuart
Stuart Clennett Delphi Berlin 10.1 |
 |
|
Ralf
  
120 Posts |
Posted - Mar 15 2017 : 10:33:48
|
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 |
 |
|
Ralf
  
120 Posts |
Posted - Mar 16 2017 : 05:53:17
|
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
|
 |
|
xequte
    
38995 Posts |
Posted - Mar 19 2017 : 16:02:43
|
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
|
 |
|
|
Topic  |
|