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 after using AutoCrop
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

JonRobertson

USA
41 Posts

Posted - Oct 20 2011 :  17:01:59  Show Profile  Reply
I'm wondering if I'm doing something wrong. I've implemented scanning using ImageEn and it works great. Then I went back and added a call to AutoCrop after the call to Acquire:

ImageEnMView.MIO.Acquire();
ImageEnMView.Proc.AutoCrop(10, CreateRGB(0, 0, 0));

Now I get an Access Violation when freeing ImageEnMView. Simplified stack:

  hyieutils.TIEBitmap.FreeAllMaps
  hyieutils.TIEBitmap.FreeImage(True)
  hyieutils.TIEBitmap.Destroy
  imageenproc.TImageEnProc.Destroy
  iemview.TImageEnMView.Destroy

At this point, when FreeAllMaps is called, fScanlinesToUnMapPtr is nil. So accessing fScanlinesToUnMapPtr.Count causes an Access Violation. Best I can tell, the problem is that TImageEnProc.fIEBitmap is being freed twice.

TImageEnMView.GetImageEnProc creates TImageEnProc and attaches itself to fImageEnProc. At that point,
fImageEnProc.FIEBitMapCreated = True
fImageEnProc.fBitMap is not assigned
fImageEnproc.fIEBitmap is assigned

Then fSelectedItem = -1 so SelectedImage is assigned zero. This causes TImageEnProc.OnBitmapChange to be called.

Both fImageEnView and fIEBitmap are assigned, so fIEBitmap is assigned frmImageEnView.IEBitmap.

Now, fImageEnView should own frmImageEnView.Bitmap. But TImageEnProc.fIEBitmapCreated is not set to False.

When I free the ImageEnMView that I created, the embedded TImageEnProc is destroyed as well. The bottom of its constructor is

  if fIEBitmapCreated then
    FreeAndNil(fIEBitmap);

Since fIEBitmapCreated is still True, the bitmap is freed twice.

I added a line to OnBitmapChange to set fIEBitmapCreated := False. But I'm not sure this is the correct fix:

procedure TImageEnProc.OnBitmapChange(Sender: TObject; destroying: boolean);
begin
  if destroying then
  begin
    fImageEnView := nil;
  end
  else if assigned(fImageEnView) then
  begin
    if assigned(fIEBitmap) then
    begin
      fIEBitmap := fImageEnView.IEBitmap;
      fBitmap := nil; // both fBitmap and fIEBitmap aren't allowed if not encapsulated
      fIEBitmapCreated := False; // ADDED THIS LINE!
    end
    else if assigned(fBitmap) then
    begin
      fBitmap := fImageEnView.Bitmap;
      if fIEBitmapCreated then
        fIEBitmap.EncapsulateTBitmap(fBitmap, true);
    end;

  end;
end;

fab

1310 Posts

Posted - Oct 24 2011 :  00:23:27  Show Profile  Reply
Please make sure that an image is selected before call ImageEnMView.Proc... methods, because these methods refers to the currently selected image.
You should write, for example:
ImageEnMView.MIO.Acquire();
if ImageEnMView.ImageCount > 0 then
begin
  // select last image
  ImageEnMView.SelectSeek(iskLast);
  ImageEnMView.Proc.AutoCrop(10, CreateRGB(0, 0, 0));
end;
Go to Top of Page

JonRobertson

USA
41 Posts

Posted - Oct 25 2011 :  09:41:36  Show Profile  Reply
Thanks. I implemented a loop in case there were multiple pages. Is there anything wrong with doing this:

ImageEnMView.MIO.Acquire();

for iLoop := 0 to ImageEnMView.ImageCount - 1 do begin
  ImageEnMView.SelectedImage := iLoop;
  ImageEnMView.Proc.AutoCrop(10, CreateRGB(0, 0, 0));
end;
Go to Top of Page

fab

1310 Posts

Posted - Oct 25 2011 :  11:56:22  Show Profile  Reply
It is ok.
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: