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

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Bug found, and another possible bug,

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
egrobler Posted - Apr 11 2014 : 17:37:04
Hi Nigel,

1) I found this small bug: (ImageEn 5.0.6)
procedure TImageEnVect.RemoveVObjData(var obj: TIEVObject);
begin
  if obj.BitmapIdx >= 0 then
  begin
    // free image data
    FreeBitmap(obj.BitmapIdx);
    obj.BitmapIdx := -1;
  end;
  // free name
  if obj.Name <> nil then
    freemem(obj.Name);
  obj.Name := nil; //please add this line
  ...
end;


2) Possible bug, removing an object by handle not working as expected.
Please see FormShow below, I add two objects called red and blue, with handles 0 and 1 respectively.
In the debugger you will have:
fObjHeapCount = 2
fObjHeap^[0].name: 'red' fObjHeap^[0].BrushStyle: bsSolid
fObjHeap^[1].name: 'blue' fObjHeap^[1].BrushStyle: bsSolid


Then click on button1
It removes the first object as expected and now we have:
fObjHeapCount = 2
fObjHeap^[0].name: '' fObjHeap^[0].BrushStyle: bsSolid
fObjHeap^[1].name: 'blue' fObjHeap^[1].BrushStyle: bsSolid


Then click on button2
It changes Brush style of the second object it works as expected:
fObjHeapCount = 2
fObjHeap^[0].name: '' fObjHeap^[0].BrushStyle: bsSolid
fObjHeap^[1].name: 'blue' fObjHeap^[1].BrushStyle: bsCross


Then click on button1 again
It removed the second object from the view but that handle was not specified.
Handle 1 should still be valid, but it is now invisible.
fObjHeapCount = 2
fObjHeap^[0].name: '' fObjHeap^[0].BrushStyle: bsSolid
fObjHeap^[1].name: 'blue' fObjHeap^[1].BrushStyle: bsCross


I would expect calling RemoveObject(0) repeatedly not to affect the other valid object handles.
In other words a request to remove object with handle x, should not visually remove an object with handle y.

Best Regards
Eric


procedure TForm1.FormShow(Sender: TObject);
begin
  with ImageEnVect1 do
  begin
    ObjName[-1] := 'red';
    ObjKind[-1] := iekBOX;
    ObjLeft[-1] := 0; ObjTop[-1] := 0;
    ObjWidth[-1] := 100; ObjHeight[-1] := 100;  ObjPenColor[-1] := clBlack;
    ObjBrushColor[-1] := clRed;
    ObjBrushStyle[-1] := bsSolid;
    ObjPenWidth[-1] := 2;
    RedHandle := AddNewObject;  //0
  end;

  with ImageEnVect1 do
  begin
    ObjName[-1] := 'blue';
    ObjLeft[-1] := 0; ObjTop[-1] := 120;
    ObjBrushStyle[-1] := bsCross;
    ObjBrushColor[-1] := clBlue;
    BlueHandle := AddNewObject; //1
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ImageEnVect1.RemoveObject(RedHandle);  //handle 0
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ImageEnVect1.ObjBrushStyle[BlueHandle] := bsHorizontal;  //handle 1
end;
4   L A T E S T    R E P L I E S    (Newest First)
xequte Posted - Apr 18 2014 : 22:01:48
Hi Eric

Sorry, I should have advised that we did address that aspect of your report. The object is now nulled.

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
egrobler Posted - Apr 18 2014 : 17:18:32
quote:
The parameter of RemoveObject is not an index, so you cannot repeatedly call:
ImageEnVect1.RemoveObject(0);


I realize that and it was not the point of my post.
The point is that the library does not check for invalid RemoveObject calls.

If I create 3 objects:

 fObjHeap^[0] -> PIEVObject  name^='first'
 fObjHeap^[1] -> PIEVObject  name^='second'
 fObjHeap^[2] -> PIEVObject  name^='third'
 fObjCount=3
 fObjHeapCount=3


and then call ImageEnVect1.RemoveObject(1)
then the variables will be:

fObjHeap^[0] -> PIEVObject  name^='first'
fObjHeap^[1] -> PIEVObject  name^='second'  //should be name:nil
fObjHeap^[2] -> PIEVObject  name^='third'
fObjCount=2
fObjHeapCount=3

You call freemem(obj.Name) but forgot to set the variable to nil.

If the user calls ImageEnVect1.RemoveObject(1) by mistake again
you will get "Invalid pointer operation" at freemem(obj.Name);
If you fix this bug, then you will run into trouble with fObjCount because will call RemoveVObjData decrement the count and make fObjHeap^[2] invisible.
Therefore you need a FreePending flag with the name :=nil bug fix as I explained above.

EXAMPLE CODE:
with ImageEnVect1 do
begin
  ObjKind[-1] := iekBOX; ObjName[-1] := 'first';
  ObjLeft[-1] := 0; ObjTop[-1] := 0; ObjWidth[-1] := 50; ObjHeight[-1] := 50;
  ObjPenColor[-1] := clBlack;
  ObjBrushColor[-1] := clRed;
  ObjBrushStyle[-1] := bsSolid;
  AddNewObject;
end;

with ImageEnVect1 do
begin
  ObjKind[-1] := iekBOX; ObjName[-1] := 'second';
  ObjLeft[-1] := 0; ObjTop[-1] := 60; ObjWidth[-1] := 50; ObjHeight[-1] := 50;
  ObjBrushColor[-1] := clBlue;
  AddNewObject;
end;

with ImageEnVect1 do
begin
  ObjKind[-1] := iekBOX; ObjName[-1] := 'third';
  ObjLeft[-1] := 0; ObjTop[-1] := 120; ObjWidth[-1] := 50; ObjHeight[-1] := 50;
  ObjBrushColor[-1] := clYellow;
  AddNewObject;
end;

ImageEnVect1.RemoveObject(1);
ImageEnVect1.RemoveObject(1); //compare behaviour when obj.Name := nil fix inside TImageEnVect.RemoveVObjData


Regards
Eric
xequte Posted - Apr 16 2014 : 14:57:41
Hi Eric

The parameter of RemoveObject is not an index, so you cannot repeatedly call:

ImageEnVect1.RemoveObject(0);

You should think of hObj as a pointer, rather than an index.


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
egrobler Posted - Apr 11 2014 : 18:37:44
Hi Nigel,

I think I now understand what happens.
If you fix the missing obj.Name = nil bug in RemoveVObjData and call ImageEnVect1.RemoveObject(0) repeatedly when fObjHeapCount>1 then fObjCount will become negative in RemoveVObject.
So I think there needs to be a flag that indicates that the object has been removed.

This seems to fix the problem, but I am not 100% sure:
Add a flag to TIEVObject:
TIEVObject = record
    FreePending : Boolean;
    ...
  end;

Then set the flag when clearing data:
procedure TImageEnVect.RemoveVObjData(var obj: TIEVObject);
begin
  obj.FreePending := True;

  if obj.BitmapIdx >= 0 then
  begin
    // free image data
    FreeBitmap(obj.BitmapIdx);
    obj.BitmapIdx := -1;
  end;
  // free name
  if obj.Name <> nil then
  begin
    freemem(obj.Name);
    obj.Name := nil;
  end;
  ...
end;


Then check the flag in RemoveObject

  procedure _RemoveObject(iObj: integer);
  var
    pobj: PIEVObject;
  begin
    pobj := GetObj(iObj);
    if pobj^.FreePending then
    begin
      Raise EIEException.Create('Dead hobj handle '+IntToStr(iObj))  //or just ignore
    end else
    begin
      UnSelObject(iObj);
      RemoveVObjData(pobj^); // remove object data
      RemoveVObject(iObj); // remove object
      if iObj = fObjHeapCount - 1 then
      // decrease the heap (but it doesn't realloc), because it is last object inserted
      dec(fObjHeapCount);
      DoVectorialChanged;
    end;
  end;


Best Regards
Eric