Jpg /Png export
Blitz3D Forums/Blitz3D Programming/Jpg /Png export| 
 | ||
| Does anyone know if any patent exists for writing these files, also anyone know of some code that does it? | 
| 
 | ||
| jpg patent expires oct 2006 png patent free | 
| 
 | ||
| There are some file exporters in the code archives i'm pretty sure I saw png the other day but i'm not 100% sure it might have been tga. There used to be a free .dll by Guy Savorie to export .jpg images, but he had a personal situation and disapeared from the indie scene a few years ago and i've lost the .dll myself, I think a few of my online friends from another programming community might well have it still if you really need it, i'll try to track it down. | 
| 
 | ||
| http://www.blitzcoder.com/cgi-bin/showcase/showcase_showentry.pl?id=snarty09252003024804&comments=no | 
| 
 | ||
| If anyone wants a PNG exporter written purely in Blitz, I could probably sort that out this weekend. Anyone interested? | 
| 
 | ||
| @all  Thanks @JFK Looks promising ill check it out now! @vinylpusher MeMeMe! | 
| 
 | ||
| Ok, I'll take Andre LaMothe's Targa exporter in C++ and change it to a PNG exporter in Blitz. How hard can it be? Should be a laugh. | 
| 
 | ||
| vinylpusher, me too! Please! | 
| 
 | ||
| The beginnings of the exporter are included below. I've got a real stinking cold right now so I'm not exactly on top form. Please excuse any stupid errors! I didn't realise quite how complex PNG is. I've got to implement LZ77 compression and CRC32 creation just to get a very basic PNG file created. This is something I will start doing tomorrow (if I get out of bed at all). pngexporter.bb ;------------------------------------------------------------------------------
; Native Blitz 3D PNG exporter
; Version 0.01
; Copyright 2005 Stefan Holmes.
; You may use this file freely so long as the text "PNG exporter by Stefan
; Holmes" appears either in your application's 'help, about' or in the main
; documentation.
;------------------------------------------------------------------------------
Function pngExport(file$,img%)
    ;--------------------------------------------------------------------------
    ;
    ; ARGUMENTS:
    ;
    ; file$     : Full path and name of the file to be saved.
    ;
    ; image%    : Valid Blitz 3D image handle.
    ;--------------------------------------------------------------------------
    ;
    ; RETURNS:
    ;
    ; Not 0 : Success.
    ;
    ; 0     : Failure.
    ;--------------------------------------------------------------------------
    DeleteFile file$ 
    fh% = WriteFile(file$) : If fh%=0 Then Return 0
    Restore pngExporter_sig
    For i=1 To 8
        Read d%
        WriteByte(fh%,d%)
    Next
    ; IHDR chunk.
    pngExporterStartChunk(fh%,13,"IHDR")
    pngExporterWriteInt(fh%,ImageWidth(img%))   ; Width                 4 bytes
    pngExporterWriteInt(fh%,ImageHeight(img%))  ; Height                4 bytes
    WriteByte(fh%,8)                            ; Bitdepth              1 byte
    WriteByte(fh%,2)                            ; Colour type           1 byte
    WriteByte(fh%,0)                            ; Compression method    1 byte
    WriteByte(fh%,0)                            ; Filter method         1 byte
    WriteByte(fh%,0)                            ; Interlace method      1 byte  
    ; IEND chunk.
    pngExporterStartChunk(fh%,0,"IEND")
    WriteInt(fh%,0)
    CloseFile fh%
    Return fh%
    
End Function
.pngExporter_sig
Data  137,80,78,71,13,10,26,10
Function pngExporterStartChunk(filehandle%,length%,chunk$)
    pngExporterWriteInt(filehandle%,length%)
    pngExporterWriteStr(filehandle%,chunk$)
End Function
Function pngExporterWriteInt(filehandle%,value%)
    ; Taken from Starfox a.k.a David Dawkin's WriteMotorolaInt function
    ; available at http://www.blitzbasic.com/codearcs/codearcs.php?code=674
    ; Thanks, Starfox.
    WriteByte(filehandle%, value% Shr 24 And $FF)
    WriteByte(filehandle%, value% Shr 16 And $FF)
    WriteByte(filehandle%, value% Shr 8 And $FF)
    WriteByte(filehandle%, value% And $FF)
End Function 
Function pngExporterWriteStr(filehandle%,strng$)
    For i% = 1 To Len(strng$)
        WriteByte( filehandle%, Asc( Mid(strng$,i%,1) ) )
    Next
End Functiontester.bb;------------------------------------------------------------------------------
; Test program for "Native Blitz 3D PNG exporter"
; Version 0.01
; Copyright 2005 Stefan Holmes.
; This code is 'public domain' without limitation or condition.
;------------------------------------------------------------------------------
Include "pngexporter.bb"
;------------------------------------------------------------------------------
img%=LoadImage("kodim20.png")
If img%>0
    Graphics ImageWidth(img%)+16,ImageHeight(img%)+22,32,2
    img%=LoadImage("kodim20.png")
    DrawImage img%,8,17
    Color 255,255,255
    Rect 7,16,GraphicsWidth()-14,GraphicsHeight()-20,False
    Color 0,0,0
    txt("Exporting PNG...")
    err%=pngExport("a_out.png",img%)
    If err%>0
        Txt("PNG saved.")
    Else
        txt("Error when saving.")
    EndIf 
    
Else
    Print "Unable to load image; exiting."
    Delay 4000
    End 
EndIf
Function txt(txt$)
    Color 0,0,0
    Rect 0,0,GraphicsWidth(),16
    Color 255,255,255
    Text 0,0,txt$
End FunctionHere is the kodim20.png test image I'm using. | 
| 
 | ||
| Slightly updated version. Still doesn't do anything useful, but I'm getting there. I might not have any more time today to work on it today, got some IRL stuff to do which takes priority :-/ EDIT: Fixed stupid CRC32 bug. should now generate correct CRC. ;------------------------------------------------------------------------------
; Native Blitz 3D PNG exporter
; Version 0.02
; Copyright 2005 Stefan Holmes.
; You may use this file freely so long as the text "PNG exporter by Stefan
; Holmes" appears either in your application's 'help, about' or in the main
; documentation.
;------------------------------------------------------------------------------
Function pngExport(file$,img%)
    ;==========================================================================
    ; DESCRIPTION
    ;
    ; Exports an image as a PNG file without recourse to an external DLL.
    ;
    ; Inspired by a request for such a function originally made by Daniel
    ; Harvey (D-Grafix) and seconded by John Blackledge.
    ; http://www.blitzbasic.com/Community/posts.php?topic=52394
    ;--------------------------------------------------------------------------
    ; PARAMETERS
    ;
    ; file$ : Full path and name of the file to be saved.
    ;
    ; img%  : Valid Blitz 3D image handle.
    ;--------------------------------------------------------------------------
    ; RETURNS
    ;
    ; >0    : Size of the written file.
    ;
    ; 0     : Failed to write file.
    ;==========================================================================
    DeleteFile file$ 
    fh% = WriteFile(file$) : If fh%=0 Then Return 0
    
    crc32bank%=pngExporterInitCRC32()
    imgwidth%=ImageWidth(img%)
    imgheight%=ImageHeight(img%)
    
    ;--------------------------------------------------------------------------
    ; PNG signature.
    WriteByte(fh%,137):WriteByte(fh%,80):WriteByte(fh%,78):WriteByte(fh%,71)
    WriteByte(fh%,13):WriteByte(fh%,10):WriteByte(fh%,26):WriteByte(fh%,10)
    ;--------------------------------------------------------------------------
    
    ;--------------------------------------------------------------------------
    ; IHDR chunk.
    pngExporterStartChunk(fh%,13,"IHDR")
    pngExporterWriteInt(fh%,imgwidth%)      ; Width                 4 bytes
    pngExporterWriteInt(fh%,imgheight%)     ; Height                4 bytes
    WriteByte(fh%,8)                        ; Bitdepth              1 byte
    WriteByte(fh%,2)                        ; Colour type           1 byte
    WriteByte(fh%,0)                        ; Compression method    1 byte
    WriteByte(fh%,0)                        ; Filter method         1 byte
    WriteByte(fh%,0)                        ; Interlace method      1 byte  
    ;--------------------------------------------------------------------------
    
    ;--------------------------------------------------------------------------
    ; Convert pixels to data stored in a bank.
    
    imgbank%=CreateBank( (imgwidth% * imgheight%) * 3 )
    imgwidth%=imgwidth%-1 : imgheight%=imgheight%-1
    
    SetBuffer ImageBuffer(img%)
    LockBuffer
    i%=0
    For y%=0 To imgheight%
        For x%=0 To imgwidth%
            ; There is no doubt a better way to do this, but it works.
            ; Taken from the BMax desaturation fader by Marc van den Dikkenberg
            ; (xlsior).
            ; http://www.blitzbasic.com/codearcs/codearcs.php?code=1282
            pixel%=ReadPixelFast(x%,y%)
            PokeByte imgbank%,i%,(pixel% And $00FF0000) Shr 16
            PokeByte imgbank%,i%+1,(pixel% And $FF00) Shr 8
            PokeByte imgbank%,i%+2,(pixel% And $FF)
            i%=i%+3
        Next
    Next 
    UnlockBuffer
    SetBuffer FrontBuffer()
    
    ; Calculate the CRC32 needed for the IDAT chunk
    crc%=pngExporterCalcCRC32(crc32bank%,imgbank%)
    ;--------------------------------------------------------------------------
    ;--------------------------------------------------------------------------
    ; IEND chunk.
    pngExporterStartChunk(fh%,0,"IEND")
    WriteInt(fh%,0)
    ;--------------------------------------------------------------------------
    FreeBank crc32bank%
    FreeBank imgbank%
    CloseFile fh%
    Return FileSize(file$)
    
End Function
Function pngExporterStartChunk(filehandle%,length%,chunk$)
    pngExporterWriteInt(filehandle%,length%)
    pngExporterWriteStr(filehandle%,chunk$)
End Function
;------------------------------------------------------------------------------
; File functions adapted from the LightWave exporter by David Dawkin (starfox).
; http://www.blitzbasic.com/codearcs/codearcs.php?code=674
;------------------------------------------------------------------------------
Function pngExporterWriteInt(filehandle%,value%)
    WriteByte(filehandle%, value% Shr 24 And $FF)
    WriteByte(filehandle%, value% Shr 16 And $FF)
    WriteByte(filehandle%, value% Shr 8 And $FF)
    WriteByte(filehandle%, value% And $FF)
End Function 
Function pngExporterWriteStr(filehandle%,strng$)
    ;==========================================================================
    ; DESCRIPTION
    ;
    ; Writes a string literal to a file with no preceeding or trailing data.
    ;--------------------------------------------------------------------------
    ; ARGUMENTS
    ;
    ; filehandle%   : Self explanatory.
    ;
    ; strng$        : String to be outputted to the file.
    ;==========================================================================
    For i% = 1 To Len(strng$)
        WriteByte( filehandle%, Asc( Mid(strng$,i%,1) ) )
    Next
End Function
;------------------------------------------------------------------------------
; CRC32 functions adapted from Recursive CRC32 Builder by Odin Jensen (ozak).
; http://www.blitzbasic.com/codearcs/codearcs.php?code=1457
;------------------------------------------------------------------------------
Function pngExporterInitCRC32%()
    ;==========================================================================
    ; DESCRIPTION
    ;
    ; Precomputes the CRC32 lookup table and stores it in a bank.
    ;--------------------------------------------------------------------------
    ; RETURNS
    ;
    ; Handle to a 256 byte bank containing a CRC32 lookup table or 0 if failed.
    ;==========================================================================
    bank%=CreateBank(256*4)
    If bank%
        For i%=0 To 255
            value%=i%
            For j%=0 To 7
                If (value% And $1) Then
                    value%=(value% Shr 1) Xor $EDB88320
                Else
                    value%=(value% Shr 1)
                EndIf
            Next
        
            PokeInt bank%,i%*4,value%
        Next
    End If 
    Return bank%
  
End Function
Function pngExporterCalcCRC32%(crcbank%,databank%)
    ;==========================================================================
    ; DESCRIPTION
    ;
    ; Computes the CRC32 value for data stored in a bank.
    ;--------------------------------------------------------------------------
    ; PARAMETERS
    ;
    ; crcbank%  : Handle to a bank containing precomputed CRC32 lookup data.
    ;
    ; databank% : Handle to a bank containing the data you wish a CRC32 value
    ;           : to be computed for.
    ;--------------------------------------------------------------------------
    ; RETURNS
    ;
    ; 32 bit CRC for the data held in the bank.
    ;==========================================================================
    crc%=$FFFFFFFF
    length%=BankSize(databank%)-1
  
    For i%=0 To length%
        byte%=PeekByte(databank%,i%)
        crc%=(crc% Shr 8) Xor (PeekInt(crcbank%,(byte% Xor (crc% And $ff))*4))
    Next
    
    Return ~crc%
    
End Function | 
| 
 | ||
| Folks, I have a quandry. I've got to implement zlib compression in order to encode an image as a PNG. Whilst I am already doing a fair amount of wheel re-inventing by writing a PNG exporter natively in Blitz, should I really re-invent (part of) zlib in order to proceed? If I do press ahead and implement the zlib part in Blitz, I would appreciate a little help from someone a little more gifted ;) (i.e. someone else write the zlib compression function). | 
| 
 | ||
| *bump* Nobody showing much interest here... you guys still alive? | 
| 
 | ||
| I'm here. I'll give the code a try when I have a moment. | 
| 
 | ||
| Thanx all | 
| 
 | ||
| hey vinylpusher, this is kind of generous of ya! anyway seems nobodys interested, but me, i could put trying to write the zlib stuff on my 'mental to-do shelf' for a while and you should pop this into code archives, seems quite good, you know. So ehh, i get round to it later (i'm busy writing stuff for my game at the moment) but this is kinda fun, if you like image file format stuff that is. personally, i only got as far as the bmp stuff, then all those compression formats kinda put me off, you know. but ehh, seems like there is adequate documentation for png... sooo that would be useful. maybe... anyway, cheers. | 
| 
 | ||
| somethingfunky: Dude, I really appreciate any support you can give. Even pseudocode or a link to useful zlib info would be received with thanks. John Pickford: Thanks, I would be happy to receive criticism and advice on moving this forward. Any code you can come up with would also be marvellous ;) All: be advised, the CRC calculation is wrong-o. PNG requires the CRC be calculated for the whole chunk (header and data) and not just the data. I'm only CRC'ing the data at the moment. Will be fixed this weekend. | 
| 
 | ||
| wellll, in that case me goes to bookmark library and whips out... http://www.libpng.org/pub/png/spec/iso/ i think you'll prolly know this one already, but you sound like maybe, you don't. now for the zlib page its... http://www.gzip.org/zlib/rfc-zlib.html pretty obvious though as the links there on the first page anyway. good luck, this would be a nice thing to have anyway wouldn't it! i'll be looking into it later in the month anyway, so there you go, a little help goes a long way, they say. :) | 
| 
 | ||
| muk: Thanks, I've got the PNG spec printed out already ;) I had a quick scan of the zlib stuff already. It scared me off but I'll have to revisit it I'm sure. To implement PNG you need zlib, to implement zlib you need Adler-32. All in all, a real PITA and laborious conversion to any other language (Blitz included). At least the Adler-32 function has a C example, which is nice and easy to convert. | 
| 
 | ||
| I suggest you look on the internet and find sites which explain how the zlid compression works, rather than trying to figure it out by looking at computer sourcecode, which might not really represent the algorithm very well. It's probably simpler than it appears. | 
| 
 | ||
| It sounds simple. I can understand the theory behind it. Compression theory hasn't changed since I read an article about it back when Amigas were more powerful than PC's. I will get around to doing it. I just need to have a few hours uninterrupted creative time :) | 
| 
 | ||
| It hurt my eyes too - too much optimization!  Perhaps the RFC referred to in the zlib FAQ would be helpful to you? http://www.zlib.net/zlib_faq.html#faq30 Also http://www.zlib.net/feldspar.html Although these articles are geared towards developers wanting to deflate things rather than inflate them, they do describe the format of zlib-compressed data, which may be helpful in understanding how to compress. I don't mean to throw pins at your bubble, but there is a zlib DLL. Might there be a libpng DLL too? | 
| 
 | ||
| Thanks octo, I've already had a read of those articles. Deflating is what is needed for the PNG exporter ;) There most likely is a DLL for this, but where's the challenge in using a DLL? :D |