It is currently Wed Jun 19, 2013 5:06 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Using ImagePluginPNG to (un)compress a memorybuffer
PostPosted: Sat Sep 02, 2006 8:57 am 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
After some experimenting I was able to use the PNG plugin to (un)compress a memory buffer using zlib compression.
Code:
; 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.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 02, 2006 9:31 am 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
Linux version
Code:
; 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


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 5:18 pm 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
This looks cool, I will see if I can get it to work.
Edit: How do I know how large output buffer I will need?

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 5:48 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.

When I wrote this code I needed to decompress a compressed swf file in memory and still be able to use png files. For that purpose it worked fine.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 5:54 pm 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
Code:
PokeL(destLen, strm\total_out)
Is that a bug? It's poking into the memory at location destLen.

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 7:06 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.

Maybe I should have used another variable name to indicate it's the address of a variable that is expected.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 7:15 pm 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
Code:
strm\avail_out = destLen
But here it wants the value? Or is it still supposed to be the pointer?

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 7:36 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 07, 2007 9:38 pm 
Offline
PureBasic Expert
PureBasic Expert
User avatar

Joined: Fri Apr 25, 2003 4:51 pm
Posts: 2716
Location: Portugal, Lisbon
Genial!

One of the Best Tips'&'Tricks...

_________________
Software: http://xipa.org
Elevator Maintenance: http://central-elevadores.pt
Good web hosting!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 08, 2007 8:05 pm 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
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:
 If err <> 0
  ProcedureReturn zerr
 EndIf

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 08, 2007 9:13 pm 
Offline
PureBasic Expert
PureBasic Expert
User avatar

Joined: Fri Apr 25, 2003 4:51 pm
Posts: 2716
Location: Portugal, Lisbon
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:
 If err <> 0
  ProcedureReturn zerr
 EndIf


Did you read VISTA SDK ???

That's the new fail error checking routine ;)

_________________
Software: http://xipa.org
Elevator Maintenance: http://central-elevadores.pt
Good web hosting!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 08, 2007 10:11 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 08, 2007 10:14 pm 
Offline
Always Here
Always Here
User avatar

Joined: Mon Sep 22, 2003 6:45 pm
Posts: 7304
Location: Norway
I didn't get an error either, but I turned on EnableExplicit.

_________________
Woa, I set up a web server.


Top
 Profile  
 
 Post subject: Re: Using ImagePluginPNG to (un)compress a memorybuffer
PostPosted: Tue Feb 16, 2010 7:59 pm 
Offline
User
User

Joined: Sat Nov 08, 2003 10:29 am
Posts: 53
Location: Austria
Just a little modification of wilberts code: manual import of the deflate and inflate functions from a lib without making use of ImagePluginPNG.

Code:
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)


Top
 Profile  
 
 Post subject: Re: Using ImagePluginPNG to (un)compress a memorybuffer
PostPosted: Tue Feb 16, 2010 8:16 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 24, 2004 2:44 pm
Posts: 4740
Location: Berlin - Germany
a bit shorter and crossplattform:
Code:
; 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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: STARGÅTE and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye