Jpg /Png export

Blitz3D Forums/Blitz3D Programming/Jpg /Png export

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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.
    ; <a href="http://www.blitzbasic.com/Community/posts.php?topic=52394" target="_blank">http://www.blitzbasic.com/Community/posts.php?topic=52394</a>
    ;--------------------------------------------------------------------------
    ; 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).
            ; <a href="http://www.blitzbasic.com/codearcs/codearcs.php?code=1282" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=1282</a>
            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).
; <a href="http://www.blitzbasic.com/codearcs/codearcs.php?code=674" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=674</a>
;------------------------------------------------------------------------------
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).
; <a href="http://www.blitzbasic.com/codearcs/codearcs.php?code=1457" target="_blank">http://www.blitzbasic.com/codearcs/codearcs.php?code=1457</a>
;------------------------------------------------------------------------------
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