Trying to figure out how to extract an image from a pack file
Trying to figure out how to extract an image from a pack file
ok I have a question... And this is perplexing all of the AIs I am trying.
I have a pack file.. it contains 19 PNG images compressed.
I allocate memory to hold the pack data when it is read. Good.
I am able to use NextPackEntry to step through the pack one entry at a time... From here I can glean the filename and the size of each chunk.
I -believe- the goal is to copy a cropped portion of this buffer to a new buffer.. So the first entry starts at 0 and has a size of X. The next entry starts at X and has a size of Y..
I do not see any tool to copy a portion of the buffer to a new buffer starting from a specific location.. Nor do I see any tools to crop memory buffers... What key component am I missing here?
Once I get this sorted, the goal is to take the new buffer, uncompress it, and then use CatchImage to pull the image out, yes?
I have a pack file.. it contains 19 PNG images compressed.
I allocate memory to hold the pack data when it is read. Good.
I am able to use NextPackEntry to step through the pack one entry at a time... From here I can glean the filename and the size of each chunk.
I -believe- the goal is to copy a cropped portion of this buffer to a new buffer.. So the first entry starts at 0 and has a size of X. The next entry starts at X and has a size of Y..
I do not see any tool to copy a portion of the buffer to a new buffer starting from a specific location.. Nor do I see any tools to crop memory buffers... What key component am I missing here?
Once I get this sorted, the goal is to take the new buffer, uncompress it, and then use CatchImage to pull the image out, yes?
Re: Trying to figure out how to extract an image from a pack file
you could use EZpack
https://www.purebasic.fr/english/viewtopic.php?t=52586
you can catch files from memory
https://www.purebasic.fr/english/viewtopic.php?t=52586
you can catch files from memory
Re: Trying to figure out how to extract an image from a pack file
I think I may have just found the originally-intended solution... UncompressPackMemory()
Gonna try it out.
Gonna try it out.
Re: Trying to figure out how to extract an image from a pack file
Hi
You can get only any pack file by knowing the file name
You can get only any pack file by knowing the file name
Code: Select all
UseZipPacker()
Path$ = #PB_Compiler_Home + "examples/sources/Data/" ; path to the PureBasic examples data/media files
PackFile$ = GetTemporaryDirectory() + "PureBasicTest.zip" ; path to the pack file which should be created and opened later
If CreatePack(0, PackFile$)
AddPackFile(0, Path$ + "world.png", "world.png")
AddPackFile(0, Path$ + "test.pref", "test.pref")
AddPackFile(0, Path$ + "CdPlayer.ico", "CdPlayer.ico")
AddPackFile(0, Path$ + "Background.bmp", "Background.bmp")
ClosePack(0)
Debug "PackFile successfully created: " + PackFile$
Else
Debug "Error creating the pack file!"
EndIf
Path$ = GetTemporaryDirectory() + "PureBasicTest/" ; path to a directory into which the pack files should be extracted
If OpenPack(0, PackFile$)
If CreateDirectory(Path$) Or FileSize(Path$) = -2
If ExaminePack(0)
While NextPackEntry(0)
text$ = PackEntryName(0)
If text$ = "CdPlayer.ico"
UncompressPackFile(0, GetTemporaryDirectory()+ text$)
Break
EndIf
Wend
EndIf
ClosePack(0)
Else
Debug "Error while creating the folder '" + Path$ + "' to unpack the archive contents!"
EndIf
Else
Debug "Error opening the pack file!"
EndIf
Egypt my love
Re: Trying to figure out how to extract an image from a pack file
I believe I have successfully used UncompressPackMemory().... if my debug messages can be believed. CatchImage() has not worked so far.
This is what my code looks like so far.
This is what my code looks like so far.
Code: Select all
If ExaminePack(PreloadPack)
PackEntryStart = 0
While NextPackEntry(PreloadPack)
PackEntrySize = PackEntrySize(PreloadPack)
PackEntryName = PackEntryName(PreloadPack)
;Debug "PackEntryName: " + PackEntryName
;Debug "PackEntrySize: " + Str(PackEntrySize)
*PackEntry = AllocateMemory(PackEntrySize * 3)
If UncompressPackMemory(PreloadPack, *PackEntry, PackEntrySize) = -1
MessageRequester("Error", PackEntryName + " could not decompress.", #PB_MessageRequester_Error)
FreeMemory(*PackEntry)
FreeMemory(*PreloadBuffer)
EndProgram()
Else
;Debug "Entry:" + PackEntryName + " decompressed."
If CatchImage(#PB_Any, *PackEntry) = 0
MessageRequester("Error", PackEntryName + " could not catch image.", #PB_MessageRequester_Error)
FreeMemory(*PackEntry)
FreeMemory(*PreloadBuffer)
EndProgram()
EndIf
EndIf
PackEntryStart = PackEntryStart + PackEntrySize
Wend
Else
MessageRequester("Error", "Failed to examine Preload.bin!", #PB_MessageRequester_Error)
FreeMemory(*PreloadBuffer)
EndProgram()
EndIfRe: Trying to figure out how to extract an image from a pack file
Code: Select all
;Load and catch an image from a zip
#PACKPLUGIN = #PB_PackerPlugin_Zip
UseZipPacker()
UsePNGImageDecoder()
UsePNGImageEncoder()
Define myimage_id.i
;-PROCEDURE
;****************************************************
;LOADS AND CATCHES A SPECIFIC IMAGE FROM A PACKFILE
;RETURNS :#FALSE ON ERROR
; VALID IMAGE ID ON SUCCESS
;****************************************************
Procedure.i imageloadfrompack(packname.s,entryname.s)
Protected packid.i, Size.i, *Buffer, Catched_Image_ID.i,Result.i
If Not FileSize(packname.s) : Debug "Packfile not found: " + packname.s + "." : ProcedureReturn #False :EndIf
packid.i = OpenPack(#PB_Any,packname.s,#PACKPLUGIN)
If Not packid : Debug packname.s + " is not a valid pack file, or corrupted." : ProcedureReturn #False : EndIf
If Not ExaminePack(packid) : Debug "Error While examining the pack.":ClosePack(packid) : ProcedureReturn #False : EndIf
While NextPackEntry(packid)
If PackEntryName(packid) = entryname.s
Size.i = PackEntrySize(packid,#PB_Packer_UncompressedSize)
*Buffer = AllocateMemory(Size.i)
If Not *Buffer : Debug "Could not allocate memory" : ClosePack(packid) : ProcedureReturn #False : EndIf
result.i = UncompressPackMemory(packid,*Buffer,Size.i,name.s)
If result <> size : Debug "Something wrong while uncompressing, size differs." : FreeMemory(*Buffer) : ClosePack(packid) : ProcedureReturn #False : EndIf
Catched_Image_ID = CatchImage(#PB_Any,*Buffer,Size)
ClosePack(packid)
FreeMemory(*Buffer)
If Not IsImage(Catched_Image_ID) : Debug "Packentry might be not an image, or need to use some imageplugin to catch" : ProcedureReturn #False : EndIf
ProcedureReturn Catched_Image_ID
EndIf
Wend
Debug "Could not find "+ entryname.s + " in pack " + packname.s+ "."
ClosePack(packid)
ProcedureReturn #False
EndProcedure
;-EXAMPLE USAGE
;CHANGE THE NAMES TO A CORRECT ZIPFILE AND ENTRYNAME
myimage_id = imageloadfrompack("MiniWorldSprites.zip","mountains.png")
SaveImage(myimage_id,"hello.png",#PB_ImagePlugin_PNG)
Re: Trying to figure out how to extract an image from a pack file
Thank you Miso. This may work, but I need something that can grab/catch every image in the pack in one sequenced shot. I have a couple of packs of 32 images and I will need to grab them repeatedly and I believe your system requires a single image to be pulled out by name. Do you have a solution that will grab everything in a pack and catch them all in one go?
Re: Trying to figure out how to extract an image from a pack file
May sound silly to open a pack then close it multiple times one after another, but works. I don't know if PB or the Windows OS caches something, but after the first unpack the other ones are lightning fast from the same archive.
Also, you can modify that code to iterate trough and catch everything from your pack in one step, store the id-s in a list or array or map.
Entryname is optional while unpacking in memory.
Also, you can modify that code to iterate trough and catch everything from your pack in one step, store the id-s in a list or array or map.
Entryname is optional while unpacking in memory.
Re: Trying to figure out how to extract an image from a pack file
I'm giving up on Packer.. I'm going to arrange my images into a sprite sheet thing and chop them up into images inside my program.
Re: Trying to figure out how to extract an image from a pack file
Why? Have you found a bug with the Packer library? It should be able to do everything you want super efficiently.Carm3D wrote: Thu Mar 06, 2025 6:02 pm I'm giving up on Packer.. I'm going to arrange my images into a sprite sheet thing and chop them up into images inside my program.
Re: Trying to figure out how to extract an image from a pack file
I don't know if it's a bug or I am just a moron, but I couldn't get it to work... Esp. CatchImage(). I'm now making my images into sprite-sheets and I'll chop them up into image sequences after loading.Quin wrote: Thu Mar 06, 2025 6:22 pm Why? Have you found a bug with the Packer library? It should be able to do everything you want super efficiently.
Re: Trying to figure out how to extract an image from a pack file
I don't know why is that good, but here's the code:
Code: Select all
;Load and catch all images from a zip, stores the ID-s in an array.
EnableExplicit
#PACKPLUGIN = #PB_PackerPlugin_Zip
UseZipPacker()
UsePNGImageDecoder()
UsePNGImageEncoder()
Global Dim Images_h(0)
;-PROCEDURE
Procedure.i load_all_images_from_pack(packname.s)
Protected packid.i, Size.i, *Buffer, Catched_Image_ID.i,Result.i
If Not FileSize(packname.s) : Debug "Packfile not found: " + packname.s + "." : ProcedureReturn #False :EndIf
packid.i = OpenPack(#PB_Any,packname.s,#PACKPLUGIN)
If Not packid : Debug packname.s + " is not a valid pack file, or corrupted." : ProcedureReturn #False : EndIf
If Not ExaminePack(packid) : Debug "Error While examining the pack.":ClosePack(packid) : ProcedureReturn #False : EndIf
While NextPackEntry(packid)
Size.i = PackEntrySize(packid,#PB_Packer_UncompressedSize)
*Buffer = AllocateMemory(Size.i)
result.i = UncompressPackMemory(packid,*Buffer,Size.i)
Images_h(ArraySize(images_h())) = CatchImage(#PB_Any,*Buffer,Size)
FreeMemory(*Buffer)
ReDim Images_h(ArraySize(Images_h())+1)
Wend
ClosePack(packid)
EndProcedure
;-EXAMPLE USAGE
;CHANGE THE NAMES TO A CORRECT ZIPFILE AND ENTRYNAME
OpenConsole("Test")
load_all_images_from_pack("MiniworldSprites2.zip")
PrintN("ID-s of loaded images")
PrintN("")
Define i.i
For i = 0 To ArraySize(images_h())-1
PrintN("Image_handle_"+RSet(Str(i),2,"0")+": "+Str(Images_h(i)))
Next i
PrintN(Str(ArraySize(Images_h()))+" images loaded.")
Input()
End
Re: Trying to figure out how to extract an image from a pack file
See this topic for an easy solution for getting file names for a pack file.
The method there even includes a way to check the integrity of the files extracted ( file size and filehash ). PB has built-in hashing functions.
https://www.purebasic.fr/english/viewtopic.php?t=42330
HP Z800 Workstation
CPU : Dual Xeon 5690 3.46GHz
RAM : 192GB RAM
GPU : NVIDIA QUADRO P5000 16GB
CPU : Dual Xeon 5690 3.46GHz
RAM : 192GB RAM
GPU : NVIDIA QUADRO P5000 16GB



