Pload()

User projects written in or related to FreeBASIC.
Thrawn89
Posts: 477
Joined: Oct 08, 2005 13:12

Pload()

Postby Thrawn89 » May 03, 2006 2:52

Well, some of you may have heard of this project already, its a library to load png files

The goal was to make a library that would load a PNG file written in FB, it was ment to be as easy as Bload(), thus the name Pload()

Observe:

Code: Select all

Screen 19, 32

'$include: 'ploader.bi'

Dim Image As Any Ptr = Pload("thegimp.png")

Put(0,0), Image, Alpha

Do: Sleep 1: Loop While Inkey$ = ""
System


It does Alpha transparancy and everything, well...currently does not support all of the Interlaced types, but thats it....

Apparently this has been compiled and tested by v1c under v0.16, so good luck: Download Ploader Here

If you wish to use 1000101's version [which I reconmend using], link is here: Download 1000101's Edit Here

It is also fast, so dont worry about that ;-)

~Leave questions/comments here

Oh and credits/thanks:

*Thrawn89: Main coder
*counting_pine: Co-coder, spent many hours going through my code
*1000101: For cleaning up a rather large mess I made due to my ignorance *much thanks*
*elcalen: Guinea pig/bringer out of closeter
*urbanfox: Nother Guinea pig - Tester on linux
*Rattrapmax6: Tester on Windows
*v1ctor: Testage, packaging and whatever else he did...oh yeah, FB


Well, thats it for now, happy coding
~Thrawn~

PS. In the example source in the file you want to change the pset to alpha and compile just the test proggie again ;-)
Last edited by Thrawn89 on Jun 27, 2006 15:17, edited 3 times in total.
v1ctor
Site Admin
Posts: 3799
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » May 03, 2006 3:08

Great job, not needing libpng and its C-hackish functions just to load an image is really nice.

Now write us a jpeg loader, you :P.
Thrawn89
Posts: 477
Joined: Oct 08, 2005 13:12

Postby Thrawn89 » May 03, 2006 3:14

v1ctor wrote:Now write us a jpeg loader, you :P.


Hahaha, look up the specification for it, and you'd be laughing too XD

~Thrawn~
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » May 03, 2006 6:51

Awesome. I remember when you were first suggesting to do this, and everyone was telling you it was pointless and a waste of time. Well you proved them wrong now didn't you? One command interface... great work.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » May 03, 2006 9:25

doesn't compile on fb .15b (both lib & example)
i think its the time i upgrade to .16b :-(

but the exe works for me, and looking at the lib source... really good work :-)
looking forward for other formats :P
Pritchard
Posts: 5492
Joined: Sep 12, 2005 20:06
Location: Ohio, USA

Postby Pritchard » May 03, 2006 9:52

Nice job Thrawn! Wow, I had no idea that you were actually releasing this ^_~;; You rock!

Do you realize how much easier this makes programming for FB users? I feel things like this are really boosting the community's power.

Irrlicht having an FB wrapper, D.J. Peters making an FB sound lib, and Thrawn releasing a fricken PNG loader :D, life is good.
redcrab
Posts: 619
Joined: Feb 07, 2006 15:29
Location: France / Luxemburg
Contact:

Postby redcrab » May 03, 2006 10:10

Wooot ! Great job !
PLOAD is so cool , that it have to be integrated directly inside BLOAD
It's so great to have

Code: Select all

BLOAD "mypic.png"

working exactly as

Code: Select all

BLOAD "mypic.bmp"

EDITBEG:
and exactly as

Code: Select all

BLOAD "mypic.jpg"

;)
EDITEND:

That's fun !
Sisophon2001
Posts: 1704
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:

Postby Sisophon2001 » May 03, 2006 10:29

Think of the bloat to everybody’s programs, and the speed loss while the images are checked for type. Some things should be left optional, or there will be no end to adding features and file formats.

I like it the way it. The syntax is easy to remember and use.

Garvan
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Postby relsoft » May 03, 2006 10:49

Purfekt!!!!! Great job!!!!

You know, I'd rarther Bload a PNG than a BMP. :*)
redcrab
Posts: 619
Joined: Feb 07, 2006 15:29
Location: France / Luxemburg
Contact:

Postby redcrab » May 03, 2006 13:35

Sisophon2001 wrote:Think of the bloat to everybody’s programs, and the speed loss while the images are checked for type. Some things should be left optional, or there will be no end to adding features and file formats.

I like it the way it. The syntax is easy to remember and use.

Garvan


Bitmap file type checking is already done inn BLOAD ... when you use .bmp file or not ... so why not .png file also...


have fun !
jofers
Posts: 1525
Joined: May 27, 2005 17:18
Contact:

Postby jofers » May 03, 2006 13:41

Because then anybody who loads an uncompressed image will have to package the code for a complete PNG loader in their program.

However, if you DON'T add file checking and let users do this:

Code: Select all

BLoad "myfile.png", Buffer As PNG
BLoad "myfile.bmp", Buffer As BMP
BLoad "myfile.bsv", Buffer As BSAVE


Then you can put the two routines in separate modules, and the bloat will only be applied to those who actually use the function. If force the type to follow a reserved keyword like "As" or "Using" you don't have to reserve keywords for PNG/BMP/BSAVE.

But, of course, the loader would have to be ported to C++ to be compatible with the rest of GfxLib.
Thrawn89
Posts: 477
Joined: Oct 08, 2005 13:12

Postby Thrawn89 » May 03, 2006 13:48

Sisophon2001 wrote:Think of the bloat to everybody’s programs, and the speed loss while the images are checked for type. Some things should be left optional, or there will be no end to adding features and file formats.

I like it the way it. The syntax is easy to remember and use.

Garvan


I have to agree with him, just include the ploader if you need it, no need to have any bloat...

Though...v1c might want to add the .bi and .a with the others in the next stable release of FB ;-)

And thanks for all the feedback you guys, glad putting off Donkey Kong 2600 and The Cube didnt go to waste ^_^

~Thrawn~
redcrab
Posts: 619
Joined: Feb 07, 2006 15:29
Location: France / Luxemburg
Contact:

Postby redcrab » May 03, 2006 14:33

Okay I understand the issue ... ;)

then BLOAD for BMP for 8 16 24 32 bpp
PLOAD for PNG in 32 bpp
so JLOAD for JPEG in 32 bpp
and GLOAD for GIF in 8 bpp
and etc ... if someone has code for it of course ;)

have fun !
counting_pine
Site Admin
Posts: 6174
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » May 03, 2006 14:34

(
A couple of minor points in your code:
- "feild" is actually spelled "field"
- Anywhere you have "int(a / 8 + [number between .75 and 1]), can be done more efficiently as (a + 7) shr 3
)


I wrote a new unfiltering routine for your project. It copes with all colour types, interlaced or uninterlaced. Basically, it converts all the rows to filter type 0. So, when you're doing subsequent processing on the scanlines, you don't have to worry about how the data is filtered.

Code: Select all

Declare Function unfilter_image() As Integer
Declare Function unfilter_pass(Byval ByteWidth As Integer, Byval Height As Integer, Byval FDist As Integer, Byval StartIndex As Uinteger = 0) As Integer

Function unfilter_image
   
    Dim As Uinteger FDist 'Filter distance
    Dim As Uinteger ByteWidth 'Row length in bytes
    Dim As Uinteger IWidth2, IHeight2
    Dim As Uinteger Bpp
    Dim As Uinteger StartIndex = 0 'Position in ScanLine()
   
    Select Case As Const Header.IColorType
        Case 0
            Bpp = Header.IBitDepth
            If Header.IBitDepth = 8 Then FDist = 1 Else FDist = 2
        Case 2
            Bpp = Header.IBitDepth * 3
            If Header.IBitDepth = 8 Then FDist = 3 Else FDist = 6
        Case 3
            Bpp = Header.IBitDepth
            FDist = 1
        Case 4
            Bpp = Header.IBitDepth * 2
            If Header.IBitDepth = 8 Then FDist = 2 Else FDist = 4
        Case 6
            Bpp = Header.IBitDepth * 4
            If Header.IBitDepth = 8 Then FDist = 4 Else FDist = 8
    End Select
   
    If Header.IInterlace = 0 Then
       
        ByteWidth = (Header.IWidth * Bpp + 7) Shr 3 + 1
        Return unfilter_pass(ByteWidth, Header.IHeight, FDist)
       
    Else
       
        '1
        IWidth2 = (Header.IWidth + 7) Shr 3
        IHeight2 = (Header.IHeight + 7) Shr 3
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '2
        IWidth2 = (Header.IWidth + 3) Shr 3
        IHeight2 = (Header.IHeight + 7) Shr 3
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '3
        IWidth2 = (Header.IWidth + 3) Shr 2
        IHeight2 = (Header.IHeight + 3) Shr 3
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '4
        IWidth2 = (Header.IWidth + 1) Shr 2
        IHeight2 = (Header.IHeight + 3) Shr 2
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '5
        IWidth2 = (Header.IWidth + 1) Shr 1
        IHeight2 = (Header.IHeight + 1) Shr 2
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '6
        IWidth2 = Header.IWidth Shr 1
        IHeight2 = (Header.IHeight + 1) Shr 1
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then
            If unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex) = 0 Then Return 0
            StartIndex += ByteWidth * IHeight2
        End If
           
        '7
        IWidth2 = Header.IWidth
        IHeight2 = Header.IHeight Shr 1
        ByteWidth = (IWidth2 * Bpp + 7) Shr 3 + 1
        If ByteWidth > 1 Then Return unfilter_pass(ByteWidth, IHeight2, FDist, StartIndex)
       
    End If
   
End Function

Function unfilter_pass(Byval ByteWidth As Integer, Byval Height As Integer, Byval FDist As Integer, Byval StartIndex As Uinteger = 0) As Integer
   
    Dim As Uinteger x, y
    Dim As Uinteger ScanLineIndex, ScanLineIndex2
    Dim As Ubyte byte1, byte2, byte3, byte4
   
    'First row
    ScanLineIndex = StartIndex
    ScanLineIndex2 = ScanLineIndex' + 1
   
    Select Case As Const ScanLine(ScanLineIndex)
        Case 0, 2 'None, dY: Do nothing
           
        Case 1, 4 'dX, Paeth
           
            For x = 1 To FDist
                ScanLineIndex2 += 1
            Next x
           
            For x = FDist + 1 To ByteWidth - 1
                ScanLineIndex2 += 1
                byte1 = ScanLine(ScanLineIndex2)
                byte2 = ScanLine(ScanLineIndex2 - FDist)
                ScanLine(ScanLineIndex2) = Cubyte(byte1 + byte2)
            Next x
           
        Case 3 'Avg
           
            For x = 1 To FDist
                ScanLineIndex2 += 1
            Next x
           
            For x = FDist + 1 To ByteWidth - 1
                ScanLineIndex2 += 1
                byte1 = ScanLine(ScanLineIndex2)
                byte2 = ScanLine(ScanLineIndex2 - FDist)
                ScanLine(ScanLineIndex2) = Cubyte(byte1 + (byte2 Shr 1))
            Next x
           
        Case Else
            'Print "Invalid filter type on row 0 (" & ScanLine(ScanLineIndex) & ")": Sleep
            Return 0
           
    End Select
   
    ScanLine(ScanLineIndex) = 0
   
    'Subsequent rows
    For y = 2 To Height
       
        ScanLineIndex += ByteWidth
        ScanLineIndex2 = ScanLineIndex
       
        Select Case As Const ScanLine(ScanLineIndex)
            Case 0 'None: Do nothing
               
            Case 1 'dX
               
                For x = 1 To FDist
                    ScanLineIndex2 += 1
                Next x
               
                For x = FDist + 1 To ByteWidth - 1
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - FDist)
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + byte2)
                Next x
                   
            Case 2 'dY
               
                For x = 1 To ByteWidth - 1
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - ByteWidth)
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + byte2)
                Next x
                   
            Case 3 'Avg
               
                For x = 1 To FDist
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - ByteWidth)
                   
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + (byte2 Shr 1))
                   
                Next x
               
                For x = FDist + 1 To ByteWidth - 1
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - ByteWidth)
                    byte3 = ScanLine(ScanLineIndex2 - FDist)
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + ((byte2 + byte3) Shr 1))
                Next x
                   
            Case 4 'Paeth
               
                For x = 1 To FDist
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - ByteWidth)
                   
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + byte2)
                   
                Next x
               
                For x = FDist + 1 To ByteWidth - 1
                    ScanLineIndex2 += 1
                    byte1 = ScanLine(ScanLineIndex2)
                    byte2 = ScanLine(ScanLineIndex2 - ByteWidth)
                    byte3 = ScanLine(ScanLineIndex2 - FDist)
                    byte4 = ScanLine(ScanLineIndex2 - ByteWidth - FDist)
                    ScanLine(ScanLineIndex2) = Cubyte(byte1 + Paeth(byte2, byte3, byte4))
                Next x
                   
            Case Else
                'Print "Invalid filter type on row " & y & " (" & ScanLine(ScanLineIndex) & ")": Sleep
                Return 0
               
        End Select
       
        ScanLine(ScanLineIndex) = 0
       
    Next y
   
    Return -1
   
End Function


To use it, just add one more line to the code.

Code: Select all

UnCompressIDAT = uncompress (@ScanLine(0), @Des_Size, @IDAT(0), Src_Size)

'insert this line:
unfilter_image


When I tried your code (compiled with -exx) on an interlaced image, I got an "out of bounds array access" in the pout routine. I can't follow the code very well, so I don't know how to fix it.

Since this function takes care of all the unfiltering, you might be able to take advantage of it to simplify your own code, so you can work out where the interlacing problems are.
Thrawn89
Posts: 477
Joined: Oct 08, 2005 13:12

Postby Thrawn89 » May 03, 2006 19:23

redcrab wrote:Okay I understand the issue ... ;)

then BLOAD for BMP for 8 16 24 32 bpp
PLOAD for PNG in 32 bpp
so JLOAD for JPEG in 32 bpp
and GLOAD for GIF in 8 bpp
and etc ... if someone has code for it of course ;)

have fun !


In a nutshell...but I would still like to see someone accually make the jpeg loader...mabey I'll find some C version and port it...*looks around*

@counting_pine:
Really great! I'll put it in and see what happends

~Thrawn~

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 3 guests