Share your advanced PureBasic knowledge/code with the community.
			
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
													
							
						
									
						Post 
					 
								by wilbert  Sat Sep 02, 2006 8:57 am 
			
			
			
			
			After some experimenting I was able to use the PNG plugin to (un)compress a memory buffer using zlib compression.
Code: Select all 
; purebasic 4.0 windows source
UsePNGImageEncoder()
Structure zstream
 next_in.l
 avail_in.l
 total_in.l
 next_out.l
 avail_out.l
 total_out.l
 msg.l
 state.l
 zalloc.l
 zfree.l
 opaque.l
 data_type.l
 adler.l
 reserved.l
EndStructure
Procedure.l Z_Compress(dest,destLen,source,sourceLen)
 
 Static strm.zstream
 strm\next_in = source
 strm\avail_in = sourceLen
 strm\next_out = dest
 strm\avail_out = destLen
 strm\zalloc = #Null
 strm\zfree = #Null
 strm\opaque = #Null
 Static zf.l
 Static err.l
 !extrn _deflateInit_
 !pushd _deflateInit_
 !popd [s_Z_Compress.v_zf]
 err = CallCFunctionFast(zf,@strm,-1,"1.2.3",SizeOf(zstream))
 If err <> 0
  ProcedureReturn zerr
 EndIf
 !extrn _deflate
 !pushd _deflate
 !popd [s_Z_Compress.v_zf]
 err = CallCFunctionFast(zf,@strm,4)
 !extrn _deflateEnd
 !pushd _deflateEnd
 !popd [s_Z_Compress.v_zf]
 If err <> 1
  CallCFunctionFast(zf,@strm)
  If err = 0
   ProcedureReturn -5
  Else
   ProcedureReturn err
  EndIf
 EndIf 
 PokeL(destLen,strm\total_out)
 ProcedureReturn CallCFunctionFast(zf,@strm)
 
EndProcedure
Procedure.l Z_Uncompress(dest,destLen,source,sourceLen)
 Static strm.zstream
 strm\next_in = source
 strm\avail_in = sourceLen
 strm\next_out = dest
 strm\avail_out = destLen
 strm\zalloc = #Null
 strm\zfree = #Null
 strm\opaque = #Null
 Static zf.l
 Static err.l
 !extrn _inflateInit_
 !pushd _inflateInit_
 !popd [s_Z_Uncompress.v_zf]
 err = CallCFunctionFast(zf,@strm,"1.2.3",SizeOf(zstream))
 If err <> 0
  ProcedureReturn zerr
 EndIf
 !extrn _inflate
 !pushd _inflate
 !popd [s_Z_Uncompress.v_zf]
 err = CallCFunctionFast(zf,@strm,4)
 !extrn _inflateEnd
 !pushd _inflateEnd
 !popd [s_Z_Uncompress.v_zf]
 If err <> 1
  CallCFunctionFast(zf,@strm)
  If err = 0
   ProcedureReturn -5
  Else
   ProcedureReturn err
  EndIf
 EndIf 
 PokeL(destLen,strm\total_out)
 ProcedureReturn CallCFunctionFast(zf,@strm)
EndProcedure
; see if it works
in = AllocateMemory(100)
out = AllocateMemory(100)
s.s = "Hello hello hello hello hello hello hello hello hello hello hello"
PokeS(in,s)
Debug Len(s)
insize.l = Len(s)
outsize.l = MemorySize(out)
Debug Z_Compress(out,@outsize,in,insize)
Debug outsize
Swap in, out
insize.l = outsize
outsize = MemorySize(out)
Debug Z_Uncompress(out,@outsize,in,insize)
Debug outsize
					Last edited by 
wilbert  on Sat Sep 02, 2006 9:57 am, edited 1 time in total.
									
 
		 
				
		
		 
	 
				
			
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
						 
													
							
						
									
						Post 
					 
								by wilbert  Sat Sep 02, 2006 9:31 am 
			
			
			
			
			Linux version
Code: Select all 
; purebasic 3.94 linux source
UsePNGImageEncoder()
Global zf.l
 
Structure zstream
 next_in.l
 avail_in.l
 total_in.l
 next_out.l
 avail_out.l
 total_out.l
 msg.l
 state.l
 zalloc.l
 zfree.l
 opaque.l
 data_type.l
 adler.l
 reserved.l
EndStructure
Procedure.l Z_Compress(dest,destLen,source,sourceLen)
 
 Static strm.zstream
 strm\next_in = source
 strm\avail_in = sourceLen
 strm\next_out = dest
 strm\avail_out = destLen
 strm\zalloc = #Null
 strm\zfree = #Null
 strm\opaque = #Null
 Static err.l
 !extrn deflateInit_
 !pushd deflateInit_
 !popd [v_zf]
 err = CallCFunctionFast(zf,@strm,-1,"1.2.3",SizeOf(zstream))
 If err <> 0
  ProcedureReturn zerr
 EndIf
 !extrn deflate
 !pushd deflate
 !popd [v_zf]
 err = CallCFunctionFast(zf,@strm,4)
 !extrn deflateEnd
 !pushd deflateEnd
 !popd [v_zf]
 If err <> 1
  CallCFunctionFast(zf,@strm)
  If err = 0
   ProcedureReturn -5
  Else
   ProcedureReturn err
  EndIf
 EndIf 
 PokeL(destLen,strm\total_out)
 ProcedureReturn CallCFunctionFast(zf,@strm)
 
EndProcedure
Procedure.l Z_Uncompress(dest,destLen,source,sourceLen)
 Static strm.zstream
 strm\next_in = source
 strm\avail_in = sourceLen
 strm\next_out = dest
 strm\avail_out = destLen
 strm\zalloc = #Null
 strm\zfree = #Null
 strm\opaque = #Null
 Static err.l
 !extrn inflateInit_
 !pushd inflateInit_
 !popd [v_zf]
 err = CallCFunctionFast(zf,@strm,"1.2.3",SizeOf(zstream))
 If err <> 0
  ProcedureReturn zerr
 EndIf
 !extrn inflate
 !pushd inflate
 !popd [v_zf]
 err = CallCFunctionFast(zf,@strm,4)
 !extrn inflateEnd
 !pushd inflateEnd
 !popd [v_zf]
 If err <> 1
  CallCFunctionFast(zf,@strm)
  If err = 0
   ProcedureReturn -5
  Else
   ProcedureReturn err
  EndIf
 EndIf 
 PokeL(destLen,strm\total_out)
 ProcedureReturn CallCFunctionFast(zf,@strm)
EndProcedure
; see if it works
in = AllocateMemory(100)
out = AllocateMemory(100)
s.s = "Hello hello hello hello hello hello hello hello hello hello hello"
PokeS(in,s)
Debug Len(s)
insize.l = Len(s)
outsize.l = 100
Debug Z_Compress(out,@outsize,in,insize)
Debug outsize
tmp = in
in = out
out = tmp
insize.l = outsize
outsize = 100
Debug Z_Uncompress(out,@outsize,in,insize)
Debug outsize 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Trond 							 
						Always Here 			
		Posts:  7446 Joined:  Mon Sep 22, 2003 6:45 pmLocation:  Norway 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Trond  Wed Feb 07, 2007 5:18 pm 
			
			
			
			
			This looks cool, I will see if I can get it to work.
			
			
									
									
						 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
						 
													
							
						
									
						Post 
					 
								by wilbert  Wed Feb 07, 2007 5:48 pm 
			
			
			
			
			It's the more or less the same as the PureZIP_UnpackMemory function from the PureZIP library. In other words ... you don't know and just have to make sure the destination buffer is large enough.
			
			
									
									
						 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Trond 							 
						Always Here 			
		Posts:  7446 Joined:  Mon Sep 22, 2003 6:45 pmLocation:  Norway 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Trond  Wed Feb 07, 2007 5:54 pm 
			
			
			
			
			Is that a bug? It's poking into the memory at location destLen.
 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
						 
													
							
						
									
						Post 
					 
								by wilbert  Wed Feb 07, 2007 7:06 pm 
			
			
			
			
			It's supposed to be that way. As a parameter you pass a memory address as you can see in the debug function used to test it. The function itself returns a status code. You pass the address of a variable that after the function is executed should contain the uncompressed size.
			
			
									
									
						 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Trond 							 
						Always Here 			
		Posts:  7446 Joined:  Mon Sep 22, 2003 6:45 pmLocation:  Norway 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Trond  Wed Feb 07, 2007 7:15 pm 
			
			
			
			
			But here it wants the value? Or is it still supposed to be the pointer?
 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
						 
													
							
						
									
						Post 
					 
								by wilbert  Wed Feb 07, 2007 7:36 pm 
			
			
			
			
			As far as I know the pointer.
I used uncompr.c from the zlib library as an example but c is not my specialty 
 You might want to look at that file but for me it has worked so far.
 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Num3 							 
						PureBasic Expert 			
		Posts:  2812 Joined:  Fri Apr 25, 2003 4:51 pmLocation:  Portugal, Lisbon
				Contact: 
				
			 
				
		 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Num3  Wed Feb 07, 2007 9:38 pm 
			
			
			
			
			Genial!
			
			
									
									
						 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Trond 							 
						Always Here 			
		Posts:  7446 Joined:  Mon Sep 22, 2003 6:45 pmLocation:  Norway 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Trond  Thu Feb 08, 2007 8:05 pm 
			
			
			
			
			It's a great trick that works very well, but this time I think I found a real bug. Shouldn't zerr be err?
Code: Select all 
 If err <> 0 
  ProcedureReturn zerr 
 EndIf 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Num3 							 
						PureBasic Expert 			
		Posts:  2812 Joined:  Fri Apr 25, 2003 4:51 pmLocation:  Portugal, Lisbon
				Contact: 
				
			 
				
		 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Num3  Thu Feb 08, 2007 9:13 pm 
			
			
			
			
			Trond wrote: It's a great trick that works very well, but this time I think I found a real bug. Shouldn't zerr be err?
Code: Select all 
 If err <> 0 
  ProcedureReturn zerr 
 EndIf
Did you read VISTA SDK ???
That's the new fail error checking routine 
 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								wilbert 							 
						PureBasic Expert 			
		Posts:  3943 Joined:  Sun Aug 08, 2004 5:21 amLocation:  Netherlands 
		
						
						
						 
													
							
						
									
						Post 
					 
								by wilbert  Thu Feb 08, 2007 10:11 pm 
			
			
			
			
			Trond wrote: Shouldn't zerr be err?
You are right of course 
I just never got an error so I didn't notice the problem.
 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								Trond 							 
						Always Here 			
		Posts:  7446 Joined:  Mon Sep 22, 2003 6:45 pmLocation:  Norway 
		
						
						
						 
													
							
						
									
						Post 
					 
								by Trond  Thu Feb 08, 2007 10:14 pm 
			
			
			
			
			I didn't get an error either, but I turned on EnableExplicit.
			
			
									
									
						 
		 
				
		
		 
	 
	
						
		
		
			
				
																			
								javabean 							 
						User 			
		Posts:  60 Joined:  Sat Nov 08, 2003 10:29 amLocation:  Austria 
		
						
						
													
							
						
									
						Post 
					 
								by javabean  Tue Feb 16, 2010 7:59 pm 
			
			
			
			
			Just a little modification of wilberts code: manual import of the deflate and inflate functions from a lib without making use of ImagePluginPNG.
Code: Select all 
ImportC "zlib.lib"
  inflateInit(*strm.l,*version.l,stream_size.l) As "_inflateInit_@12"
  inflate(*strm.l,flush.l) As "_inflate@8"
  inflateEnd(*strm.l) As "_inflateEnd@4"
  deflateInit(*strm.l,level.l,*version.l,stream_size.l) As "_deflateInit_@16"
  deflate(*strm.l,flush.l) As "_deflate@8"
  deflateEnd(*strm.l) As "_deflateEnd@4"
EndImport
Structure zstream
  next_in.l
  avail_in.l
  total_in.l
  next_out.l
  avail_out.l
  total_out.l
  msg.l
  state.l
  zalloc.l
  zfree.l
  opaque.l
  data_type.l
  adler.l
  reserved.l
EndStructure
#Z_OK            =  0
#Z_STREAM_END    =  1
#Z_NEED_DICT     =  2
#Z_ERRNO         = -1
#Z_STREAM_ERROR  = -2
#Z_DATA_ERROR    = -3
#Z_MEM_ERROR     = -4
#Z_BUF_ERROR     = -5
#Z_VERSION_ERROR = -6
#Z_NO_FLUSH      =  0
#Z_PARTIAL_FLUSH =  1
#Z_SYNC_FLUSH    =  2
#Z_FULL_FLUSH    =  3
#Z_FINISH        =  4
#Z_BLOCK         =  5
Global version$ ="1.2.3"
Procedure.l Z_Compress(*dest.l,*destLen.l,*source.l,sourceLen.l)
  Static strm.zstream
    strm\next_in    = *source
    strm\avail_in   = sourceLen
    strm\next_out   = *dest
    strm\avail_out  = *destLen
    strm\zalloc     = #Null
    strm\zfree      = #Null
    strm\opaque     = #Null
  
  Static err.l
  err.l = deflateInit(@strm,-1,@version$,SizeOf(zstream))
  
  If err <> 0
    ProcedureReturn err
  EndIf
  err = deflate(@strm,#Z_FINISH)
  If err <> 1
    deflateEnd(@strm)
    If err = 0
     ProcedureReturn #Z_BUF_ERROR
    Else
     ProcedureReturn err
    EndIf
  EndIf
  
  PokeL(*destLen,strm\total_out)
  ProcedureReturn deflateEnd(@strm)
EndProcedure
Procedure.l Z_Uncompress(*dest.l,*destLen.l,*source.l,sourceLen.l)
  Static strm.zstream
    strm\next_in    = *source
    strm\avail_in   = sourceLen
    strm\next_out   = *dest
    strm\avail_out  = *destLen
    strm\zalloc     = #Null
    strm\zfree      = #Null
    strm\opaque     = #Null
  
  Static err.l
  err.l = inflateInit(@strm,@version$,SizeOf(zstream))
  If err <> 0
    ProcedureReturn err
  EndIf
  err = inflate(@strm,#Z_FINISH)
  If err <> 1
    inflateEnd(@strm)
    If err = 0
     ProcedureReturn #Z_BUF_ERROR
    Else
     ProcedureReturn err
    EndIf
  EndIf
  PokeL(*destLen,strm\total_out)
  ProcedureReturn inflateEnd(@strm)
EndProcedure
; see if it works
in = AllocateMemory(100)
out = AllocateMemory(100)
s.s = "Hello hello hello hello hello hello hello hello hello hello hello"
PokeS(in,s)
Debug "Uncompressed: " + PeekS(@s)
insize.l = Len(s)
outsize.l = MemorySize(out)
Debug Z_Compress(out,@outsize,in,insize)
Debug "Compressed: "+ PeekS(out,outsize)
Swap in, out
insize.l = outsize
outsize = MemorySize(out)
Debug Z_Uncompress(out,@outsize,in,insize)
Debug "Uncompressed: "+ PeekS(out,outsize) 
		 
				
		
		 
	 
	
						
		
		
			
				
								ts-soft 							 
						Always Here 			
		Posts:  5756 Joined:  Thu Jun 24, 2004 2:44 pmLocation:  Berlin - Germany 
		
						
						
													
							
						
									
						Post 
					 
								by ts-soft  Tue Feb 16, 2010 8:16 pm 
			
			
			
			
			a bit shorter and crossplattform:
Code: Select all 
; Autor: Thomas (ts-soft) Schulz
; PB-Version: 4.xx
; OS: windows/linux/MacOS
CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC #PB_Compiler_Home + "purelibraries/linux/libraries/zlib.a"
CompilerCase #PB_OS_MacOS
  ImportC "/usr/lib/libz.dylib"
  CompilerCase #PB_OS_Windows
    ImportC "zlib.lib"
CompilerEndSelect
  compress2(*dest, *destLen, *source, sourceLen, level)
  uncompress(*dest, *destLen, *source, sourceLen)
EndImport
Procedure zipPackMemory(*source, sourceLen = #PB_Default, level = #PB_Default)
  Protected *dest, destLen
  
  If level < #PB_Default Or level > 9 : level = #PB_Default : EndIf
  If *source
    If sourceLen = #PB_Default : sourceLen = MemorySize(*source) : EndIf
    destLen = sourceLen + 13 + (Int(sourceLen / 100))
    *dest = AllocateMemory(destLen)
    If *dest
      If Not compress2(*dest, @destLen, *source, sourceLen, level)
        *dest = ReAllocateMemory(*dest, destLen)
        ProcedureReturn *dest
      EndIf
    EndIf
  EndIf
EndProcedure
Procedure zipUnpackMemory(*source, *dest)
  Protected sourceLen = MemorySize(*source)
  Protected destLen = MemorySize(*dest)
  If Not uncompress(*dest, @destLen, *source, sourceLen)
    ProcedureReturn destLen
  EndIf
EndProcedure
Greetings
Thomas