One option, at least in this case, would be to store and free the images in swapcolor itself, like so:
FUNCTION swapcolor& (handle&, oldcolor~&, newcolor~&)
DIM m AS _MEM
DIM a&
DIM c AS _UNSIGNED LONG
STATIC perma_handle AS LONG 'save the handle between function calls
IF perma_handle < -1 THEN _FREEIMAGE perma_handle 'if you've used this swapcolor before, then free the old screen
perma_handle = _COPYIMAGE(handle&, 32) 'get a copy of the screen
swapcolor& = perma_handle 'and assign it to the FUNCTION so we can return it back for use elsewhere
m = _MEMIMAGE(swapcolor&)
DO
IF _MEMGET(m, m.OFFSET + a&, _UNSIGNED LONG) = oldcolor~& THEN _MEMPUT m, m.OFFSET + a&, newcolor~&
a& = a& + 4
LOOP UNTIL a& = m.SIZE
_MEMFREE m
END FUNCTION ' swapcolor&