Trying to figure out how to extract an image from a pack file

Just starting out? Need help? Post your questions and find answers here.
Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Trying to figure out how to extract an image from a pack file

Post by Carm3D »

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?
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Trying to figure out how to extract an image from a pack file

Post by idle »

you could use EZpack
https://www.purebasic.fr/english/viewtopic.php?t=52586
you can catch files from memory
Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Re: Trying to figure out how to extract an image from a pack file

Post by Carm3D »

I think I may have just found the originally-intended solution... UncompressPackMemory()

Gonna try it out.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Trying to figure out how to extract an image from a pack file

Post by RASHAD »

Hi
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
Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Re: Trying to figure out how to extract an image from a pack file

Post by Carm3D »

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.

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()
			EndIf
miso
Enthusiast
Enthusiast
Posts: 491
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Trying to figure out how to extract an image from a pack file

Post by miso »

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)

Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Re: Trying to figure out how to extract an image from a pack file

Post by Carm3D »

miso wrote: Thu Mar 06, 2025 4:42 am

Code: Select all

;Load and catch an image from a zip
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?
miso
Enthusiast
Enthusiast
Posts: 491
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Trying to figure out how to extract an image from a pack file

Post by miso »

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.
Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Re: Trying to figure out how to extract an image from a pack file

Post by Carm3D »

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.
Quin
Addict
Addict
Posts: 1135
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Trying to figure out how to extract an image from a pack file

Post by Quin »

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.
Why? Have you found a bug with the Packer library? It should be able to do everything you want super efficiently.
Carm3D
Enthusiast
Enthusiast
Posts: 103
Joined: Mon Feb 17, 2025 10:04 am

Re: Trying to figure out how to extract an image from a pack file

Post by Carm3D »

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.
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.
miso
Enthusiast
Enthusiast
Posts: 491
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Trying to figure out how to extract an image from a pack file

Post by miso »

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
Mohawk70
Enthusiast
Enthusiast
Posts: 404
Joined: Thu May 11, 2006 1:04 am
Location: Florida, USA

Re: Trying to figure out how to extract an image from a pack file

Post by Mohawk70 »

RASHAD wrote: Thu Mar 06, 2025 1:27 am Hi
You can get only any pack file by knowing the file name
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
Post Reply