QB64 Phoenix Edition
PCopy vs. _CopyImage - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: PCopy vs. _CopyImage (/showthread.php?tid=3837)



PCopy vs. _CopyImage - NakedApe - 07-27-2025

Since it's so quiet around here, I'll ask a question I've been wondering about...

After getting shot down by Steve on my image handling and creating memory leaks a couple weeks ago [Image Issues, Post #5], I wanted to run this by the Council of Wise Men.  In this little prog PCopy and _CopyImage seem to be inter-changeable. I'm not using PCopy for page flipping, just simply for copying the _Display to a virtual screen or copying one image to another screen. It seems like using PCopy is less likely to get me in trouble with over-writing image handles and creating leaks. 

So is there anything I should know about the difference between these two commands in this situation?

If you remark out line 26 (_CopyImage) and activate line 27 (PCopy), both versions work fine as written... Thanks.

Code: (Select All)
Screen _NewImage(500, 500, 32)
Dim Image&, image2&
$Color:32
_PrintMode _KeepBackground: _ScreenMove _Middle: Randomize Timer
start:
Image& = _NewImage(500, 500, 32) '      create 2 virtual screens
image2& = _NewImage(500, 500, 32)
Cls: Color Gray
Locate 12, 11: Print "Press a Key to Record Screen. <ESC> to End."
_Delay .65: _KeyClear

Do: Color _RGB32(Rnd * 255, Rnd * 255, Rnd * 255, Rnd * 215 + 40)
    _PrintString (Rnd * _Width, Rnd * _Height), Chr$(Int(Rnd * 255 + 1))
    PCopy _Display, Image& '            save current screen to image& IN A LOOP USING PCOPY <<<<
    _Limit 240
Loop Until _KeyHit

If _KeyDown(27) Then
    _FreeImage Image&
    _FreeImage image2& '
    System '                            off ramp
End If
Cls: Color ChartReuse
Locate 10, 26: Print "Press a key.": Sleep
'                                              copy image to 2nd screen for testing
image2& = _CopyImage(Image&, 32)
'PCopy Image&, image2& '                        these both work <<<<

_PutImage , image2&
Color White: Locate 17, 17: Print "COPIED SCREEN... PRESS A KEY!"
Sleep
_FreeImage Image& '                    free images
_FreeImage image2& '
GoTo start



RE: PCopy vs. _CopyImage - DSMan195276 - 07-27-2025

They're not equivalent, the `_CopyImage()` version is leaking memory. The naming is a bit confusing but `PCopy` is basically an older version of `_PutImage` rather than `_CopyImage()`. That said you would be right that using PCopy is getting you in less trouble Big Grin But you can use `_PutImage` to use the 'new' image commands and still stay out of trouble.

The leak is because `_CopyImage()` creates a new image and returns a new handle to it, so when you do `image2& = _CopyImage()` the previous handle stored in `image2&` (returned from the `_NewImage()` call) is overwritten and lost. When you do the `_FreeImage image2&` at the end, you're freeing the handle returned from `_CopyImage()` but the original handle from `_NewImage()` is not freed (and you also can't free yourself it at that point because you no longer know what it was).

A fix would be to do a `_FreeImage image2&` right before the `Image2& = _CopyImage()` (so, you free the old handle before you overwrite it). Alternatively you could store the handle to the copied image in a new integer variable, so - `image3& = _CopyImage()`, `_PutImage , image3&` and then add an extra `_FreeImage image3&` at the end. That way you free all three images at the end, rather than just two of them.


RE: PCopy vs. _CopyImage - SMcNeill - 07-27-2025

PCopy is a great tool for making a quick copy of a screen and then restoring it afterwards.  I highly recommend it for its simplicity for most folks.  Only problem it has, that can be a PITA is.... How does one ever free that copy once you're done with it?

PCOPY 0, 1

So the above made a copy of the active display (0) and saved it as copy (1).... Now we can overwrite that copy (1) just by issuing the command again, but... how the heck do we free it when we're completely done with it??

Code: (Select All)
PCopy 0, image
_FreeImage image

The above will error out on us.  We can't just _Freeimage that PCOPY and clear it from memory.   It tends to hang around and last as long as they existing display does -- and that might not be what you want, if you're shooting to preserve minimal resources in your program.



_CopyImage lets us make a copy of the screen just like PCOPY does, but it doesn't allow for safe overwriting of the screen like PCOPY.

FOR i = 1 TO 10
   PCOPY 0, 1
NEXT

The above simply makes a copy of the display in copy(1), and then overwrites it automatically.   You can't ever really get rid of Page(1) and free it from memory, but you can safely overwrite it.

FOR i = 1 TO 10
    image = _COPYIMAGE(0)
NEXT

The above will now make 10 copies of screen 0 and assign them screen handle values.  Since those handles are being stored in the same variable, the reference variable is being overwritten but those copies of the image are still floating around in memory.  _COPYIMAGE won't use the same page like PCOPY will, so it doesn't overwrite the same block of memory repeatedly like PCOPY would.

Note, however, that with  _COPYIMAGE you have the ability to _FREEIMAGE those handles completely.  You just have to do it manually as the program won't do any automagic clean up for you.



Note that you're getting the both of both worlds with the way you're doing things.

image2& = _newimage(x , y, z)   <-- you set a static screen which is the same as your original screen
PCOPY image, image2&   <-- you use PCOPY to store the first screen on that static screen, without creating a whole new handle
_FREEIMAGE image2A  <-- you then free that handle when you're done with it.

This works for you because everything lines up and matches properly.  If image2 was a different width, height, bit depth than your other screen, it couldn't just autocopy over like this and would toss an error for you.

Personally, I'm of the habit of just making certain I always use _FREEIMAGE religiously in my code, but the way you're doing things here looks to me like it should work fine and without issues.   Just be careful of the pitfalls no matter which style you use, and code in the manner that suits you the best.  The commands aren't identical, and each has its own drawbacks and issues to consider and be careful of.  Just choose the method you like best and be careful of any memory leaks or impossible to free images.  Wink


RE: PCopy vs. _CopyImage - NakedApe - 07-27-2025

Thanks, DSMan and Steve! That really helps clear things up. I *think* I get it now.  Wink