Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
graceful way to test for a valid image handle such as before doing _FreeImage?
#1
This problem came up earlier, where I did a _FreeImage on an image that had already been freed. 

It leads me to wonder: is there a way to determine if an image handle is valid, other than error trapping? 

Example 1: error when doing _FreeImage on an invalid image handle:

Code: (Select All)
Dim image1 As Long
Dim MaxRow As Integer

Screen _NewImage(640, 480, 32)
Cls , _RGB32(0, 0, 255)

MaxRow = _Height / _FontHeight

image1 = _NewImage(100, 100, 32)

_Dest image1
Cls , _RGB32(255, 0, 0)

_PutImage (0, 0), image1, 0

_Dest 0
Color _RGB32(0, 0, 0), _RGB32(255, 255, 0)
Locate MaxRow - 3, 1: Print "Press any key";
Sleep

Screen 0
If image1 < -1 Or image1 > 0 Then _FreeImage image1

' The next line will fail with an Invalid Handle error:
If image1 < -1 Or image1 > 0 Then _FreeImage image1
' QUESTION: How can we gracefully test that image1 is a valid image before doing a _FreeImage?

Example 2: one way to handle the error, kind of kludgey but works:

Code: (Select All)
Dim Shared m_ProgramPath As String: m_ProgramPath = Left$(Command$(0), _InStrRev(Command$(0), "\")) ' executable path
Dim Shared m_ProgramName As String: m_ProgramName = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1) ' executable filename
Dim Shared ErrNum As Long
Dim Shared ErrLine As Long

Main
End

FreeImageErrorHandler:
ErrNum = Err
ErrLine = _ErrorLine
Resume Next

Sub Main

    Dim image1 As Long
    Dim MaxRow As Integer

    Screen _NewImage(640, 480, 32)
    Cls , _RGB32(0, 0, 255)

    MaxRow = _Height / _FontHeight

    image1 = _NewImage(100, 100, 32)

    _Dest image1
    Cls , _RGB32(255, 0, 0)

    _PutImage (0, 0), image1, 0

    _Dest 0
    Color _RGB32(0, 0, 0), _RGB32(255, 255, 0)
    Locate MaxRow - 3, 1: Print "Press any key";
    Sleep

    Screen 0

    FreeImage image1

    ' The next line would cause an Invalid Handle error without error handling code
    FreeImage image1

    ' QUESTION: Do we just have to do On Error Goto or
    '           is there a way to gracefully test that image1 is a valid image
    '           before doing a _FreeImage?

    Cls
    Print "Handled error gracefully"

End Sub ' Main

Sub FreeImage (MyImage As Long)
    ErrNum = 0
    On Error GoTo FreeImageErrorHandler
    If MyImage < -1 Or MyImage > 0 Then _FreeImage MyImage
    On Error GoTo 0

    ' Ignore invalid handle error but quit if something else
    If ErrNum <> 0 Then
        If ErrNum <> 258 Then
            _MessageBox m_ProgramName, "Error " + _ToStr$(ErrNum) + " at line " + _ToStr$(ErrLine), "error"
            System
        End If
    End If
End Sub ' FreeImage
Reply
#2
(11-10-2025, 08:58 PM)madscijr Wrote: It leads me to wonder: is there a way to determine if an image handle is valid, other than error trapping? 
No because it is never safe to do that. Image handles get reused, it's impossible for the code you described to tell the difference between when the original image hasn't been free'd yet or when the image handle _was_ free'd and has since been reused by a completely unrelated `_NewImage` call. This issue also means your `ON ERROR` approach is not safe either, for the same reason - sometimes your second `_FreeImage` call _will_ work, but will be freeing a completely unrelated image you created with `_NewImage` somewhere else in the code.

You simply _have_ to properly track whether an image has been free'd and then avoid doing anything with it after that point. Ex. When you do the first `_FreeImage`, set `image1` to 0, that way the old handle is no longer in the variable when you go to check it again and the stale handle is no longer there to be free'd by mistake.
Reply
#3
Code: (Select All)

SUB FreeImage (handle AS LONG)
   IF handle < -1 THEN 
     _FREEIMAGE handle
    handle = 0
   END IF
END SUB

Just write your own freeimage routine and have it *always* set to handle back to 0 when it's freed the handle.

If a handle isn't loaded at all, then it's going to be 0.
If a handle is > 0 then it's going to be a screen handle and not needing to be freed.
Only LOAD when handles are 0 or -1, and only FREE when the handle is < -1 and then set the handle back to 0.

It's about the easiest way to deal with the issue that I know of.
Reply
#4
Thanks for answering! 
While I think it's kind of silly that QB64/PE doesn't provide some way to track & test whether a variable is currently associated with a valid image, it's not THAT big a deal, and I'll just keep in mind to make sure to keep track of that. QB64 compiles to C, so I'm not that surprised we have to do some of that manually, the trade-off being that because our programs compile to C, they can be FAST! 
Thanks again guys
Reply
#5
I tend to go with 0 simply as it's an uninitialized variable value and also what we consider in most things to be FALSE.    (And anyone trying to _FreeImage 0 is *really* doing  something wrong to begin with.  Tongue )
Reply
#6
Either -1 or 0 works for me - great idea, nice and simple. Thanks!
Reply
#7
-1 just means it wasn't initialized properly.   For example you try to _LOADIMAGE and spell the name or path wrong, so the file can't be found and can't load.  It doesn't mean it ever existed or was freed properly.   If you need that information, store it as something uniquely obscure like using a SINGLE to hold the value -0.5, or whatnot.
Reply
#8
(11-11-2025, 03:34 PM)SMcNeill Wrote: -1 just means it wasn't initialized properly.   For example you try to _LOADIMAGE and spell the name or path wrong, so the file can't be found and can't load.  It doesn't mean it ever existed or was freed properly.   If you need that information, store it as something uniquely obscure like using a SINGLE to hold the value -0.5, or whatnot.
Uniquely obscure, I like it!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Test to post a new Thread + question 32 or 64 bit Rudy M 2 538 09-09-2025, 04:10 PM
Last Post: Rudy M
  A strange experience with forum posting an image TempodiBasic 2 521 06-17-2025, 06:01 AM
Last Post: TempodiBasic
  QB64PE programming challenge? auto-convert image to photoreal etch-a-sketch drawing madscijr 9 1,805 02-14-2025, 05:49 PM
Last Post: madscijr
  Got a slow PC? Test these changes, kindly! SMcNeill 7 1,712 05-16-2024, 09:59 PM
Last Post: grymmjack
  When to free an image? James D Jarvis 5 1,129 04-16-2023, 08:55 PM
Last Post: OldMoses

Forum Jump:


Users browsing this thread: 1 Guest(s)