Undefined reference to `PNG_LoadFile@16'

General FreeBASIC programming questions.
lassar
Posts: 300
Joined: Jan 17, 2006 1:35
Contact:

Re: Undefined reference to `PNG_LoadFile@16'

Postby lassar » Jul 18, 2018 11:41

caseih wrote:
lassar wrote:The freebasic 1.05 compiler I am using is 32-bit.
So the result from this code is 4?

Code: Select all

dim as integer ptr g
print sizeof(g)

It would probably help if you posted a complete, self-contained, compile-able example that illustrated this apparent bug. And a link to where the .bi and .a files are.


Here's a link to PngLib


Showpng3.bas

Code: Select all

'
' This sample show work with PNGlib and FBGfx
' Bugs: Crash palette in palette's PNG images with more 128 colors...
'       Dont work with 16-colors PNG...
' True color PNG images worked no problem...
'
' for work need PNGlib of course...
' take it here: http://antarman.nm.ru/files/FreeBASIC/PNGLIB.zip
'
' p.s. It all some green, green BETA...
'
#lang "fblite"

#include once "pnglib2.bi"
#include once "fbgfx.bi"

'$Dynamic


 

DECLARE FUNCTION LoadPNG(byval filename$)
DECLARE SUB ShowPng(Figure$)
DECLARE SUB LoadDirPng()


' Demo main part:

screenres 640,480,32,,&H01
    PRINT "Press any key to see car"
    SLEEP
    ShowPNG "car.png"
    DO:LOOP UNTIL INKEY$ = ""
    DO:LOOP UNTIL INKEY$ <> ""
    LoadDirPng
    SLEEP
    END

Option Nogosub

Function LoadPNG(byval Filename$)
' function load PNG and return pointer to image in FBGfx format...
   dim png_image AS PNGINFO
   dim as ubyte ptr PngSource,palete,VideoPtr


   if PNG_Init(@png_image)=0 then return 0
   if PNG_LoadFile(@png_image, Filename$)=0 then return 0
   if PNG_Decode(@png_image)=0 then return 0

   palete=png_image.pPNGPalette
   PngSource=png_image.lpOutput
   PNG_OutputRaw(@png_image,PngSource,0)
    VideoPtr = SCREENPTR
' It may be made in one cycle, but it will be slowly...

    NumberOfDwords% = 640 * 480
   if Palete=0 then
        SCREENLOCK
      ASM
         MOV EBX,[NumberOfDwords%]
         MOV ESI,[PngSource]
          MOV EDI,[VideoPtr]
          MOV ECX,[NumberOfDwords%]
      DoItAgain:
            MOV EAX,0
            LODSB
            SHL EAX,8
            LODSB
            SHL EAX,8
            LODSB
            STOSD
        LOOP    DoItAgain
      END ASM
        SCREENUNLOCK
    else
        SCREENLOCK
      ASM
         MOV EBX,[NumberOfDwords%]
         MOV ESI,[PngSource]
          MOV EDI, [VideoPtr]
          MOV ECX,[NumberOfDwords%]
      DoItAgain2:
          MOV EAX,0
          LODSB
         MOV EBX,EAX
         ADD EAX,EBX
         ADD EAX,EBX
            PUSH ESI
            MOV ESI,[palete]
            ADD ESI, EAX
            MOV EAX,0
            LODSB
            SHL EAX,8
            LODSB
            SHL EAX,8
            LODSB
            STOSD
            POP ESI
      LOOP DoItAgain2
      END ASM
        SCREENUNLOCK
    end if

   PNG_Cleanup(@png_image)

    FUNCTION = sprite
end function

Option GoSub

SUB ShowPng(PngFile$)
    LoadPNG PngFile$
END SUB


SUB LoadDirPng()
    Fn$ = DIR$("DATA\*.PNG")
    WHILE Fn$ <> ""
        FilePath$ = CURDIR$ + "\DATA\" +  Fn$
        ShowPng FilePath$
        Fn$ = DIR$
    WEND
END SUB



pnglib2.bi

Code: Select all

'=============================================================================='
'                      +--\ |\  | +----   |    | +---\                         '
'                      |  | | \ | | __    |    | |___/                         '
'                      +--/ |  \| |   \   |    | |   \                         '
'                      |    |   | +---/   +--- ' +---/                         '
'=============================================================================='
' PNGLIB v1.0                                                                  '
'
' Include file for use with FreeBasic
'                                                                              '
'   PNGlib version 1.0
' Written by Thomas Bleeker. (C) 2002.                                         '
' Thomas@MadWizard.org                                                         '
' www.MadWizard.org                                                            '
'------------------------------------------------------------------------------'

' note: total size of PNGINFO structure has to be a multiple of 4 bytes
#ifndef __png_library__

#define __png_library__
#inclib "pnglib2"

type PNGINFO field=1
   iWidth        as integer         ' Width of image
   iHeight        as integer         ' Height of image
   dwLastError     as integer         ' Last error code (PNGLIB_ERR_*)
   nColors        as integer         ' Number of palette entries, if present
   PNGColorType  as byte            ' Original PNG color type (PNG_CT_*)
   PNGBitDepth     as byte               ' Original PNG bit depth (bits/sample)
   PNGInterlaced as byte            ' Interlace method (PNG_IM_*)

   ' The following structure members are used internally
   ' by PNGlib. You should not rely in any way on these values,
   ' nor assume they will be present in later versions.
   ' They are included *only* to reserve space for them.

   lpPNGData     as byte ptr         ' pointer to data in PNG file
   lnPNGData     as integer         ' length of data pointed to by lpPNGData
   lpCurrent     as byte ptr         ' 'current pointer', used internally
   lpOutput     as byte ptr         ' pointer to decompressed (unfiltered) output data, used internally
   lnOutput     as integer         ' size of output data pointed to by lpOutput
   pPNGPalette   as byte ptr         ' pointer to data in PLTE chunk
   dwLoadType     as integer         ' type of data currently loaded (PNGI_LT_*)
   pHeader        as byte ptr         ' pointer to raw IHDR chunk *data* (&chunk+8)
   pIDAT        as byte ptr         ' pointer to start of first IDAT chunk
   curState     as integer         ' PNGI_STATE_*
end type

'/******************************************************************************
'   Function declararations
' ******************************************************************************/

   declare function PNG_Init         stdcall alias "PNG_Init"         (byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_Cleanup      stdcall alias "PNG_Cleanup"      (byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_LoadFile      stdcall alias "PNG_LoadFile"      (byval pPNGInfo as PNGINFO ptr, byval lpFileName as string) as integer
   declare function PNG_LoadResource   stdcall alias "PNG_LoadResource"   (byval pPNGInfo as PNGINFO ptr, byval hInstance as integer, byval lpResName as string) as integer
   declare function PNG_LoadCustom   stdcall alias "PNG_LoadCustom"      (byval pPNGInfo as PNGINFO ptr, byval lpData as byte ptr, byval lnData as integer) as integer
   declare function PNG_Decode      stdcall alias "PNG_Decode"         (byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_GetPalette   stdcall alias "PNG_GetPalette"      (byval pPNGInfo as PNGINFO ptr, byval lpOutput as any ptr, byval dwFormat as integer) as integer
   declare function PNG_OutputRaw   stdcall alias "PNG_OutputRaw"      (byval pPNGInfo as PNGINFO ptr, byval lpDest as byte ptr, byval dwFormat as integer) as integer
   declare function PNG_CreateBitmap   stdcall alias "PNG_CreateBitmap"   (byval pPNGInfo as PNGINFO ptr, byval hWndCompatible as integer, byval dwFormat as integer, bDDB as integer) as integer

'/******************************************************************************
'   Copyproc types, used to build the PNG_OUTF_* values
' ******************************************************************************/

#define   PNGCP_X_X            0
#define   PNGCP_16_16            1
#define   PNGCP_16_16_BGR         2
#define   PNGCP_16_16_BGR_SA      3
#define   PNGCP_16_16_BGRA      4
#define   PNGCP_16_16_SA         5
#define   PNGCP_16_8            6
#define   PNGCP_16_8_BGR         7
#define   PNGCP_16_8_BGR_SA      8
#define   PNGCP_16_8_BGRA         9
#define   PNGCP_16_8_SA         10
#define   PNGCP_2_4            11
#define   PNGCP_8_8_BGR         12
#define   PNGCP_8_8_BGR_SA      13
#define   PNGCP_8_8_BGRA         14
#define   PNGCP_8_8_SA          PNGCP_16_8

'/******************************************************************************
'   Output formats
' ******************************************************************************/

#define PNG_OUTF_G1_G1         &h00010100+PNGCP_X_X
#define PNG_OUTF_G2_G2         &h00020000+PNGCP_X_X
#define PNG_OUTF_G2_G4         &h00020100+PNGCP_2_4
#define PNG_OUTF_G4_G4         &h00040100+PNGCP_X_X
#define PNG_OUTF_G8_G8         &h00080100+PNGCP_X_X
#define PNG_OUTF_G16_G16      &h00100000+PNGCP_16_16
#define PNG_OUTF_G16_G8         &h00100100+PNGCP_16_8

#define PNG_OUTF_T8_T8_BGR      &h02080100+PNGCP_8_8_BGR
#define PNG_OUTF_T16_T16_BGR   &h02100000+PNGCP_16_16_BGR
#define PNG_OUTF_T16_T8_BGR      &h02100100+PNGCP_16_8_BGR

#define PNG_OUTF_P1_P1         &h03010100+PNGCP_X_X
#define PNG_OUTF_P2_P2         &h03020000+PNGCP_X_X
#define PNG_OUTF_P2_P4         &h03020100+PNGCP_2_4
#define PNG_OUTF_P4_P4         &h03040100+PNGCP_X_X
#define PNG_OUTF_P8_P8         &h03080100+PNGCP_X_X

#define PNG_OUTF_GA8_GA8      &h04080000+PNGCP_X_X
#define PNG_OUTF_GA8_G8         &h04080100+PNGCP_8_8_SA
#define PNG_OUTF_GA16_GA16      &h04100000+PNGCP_16_16
#define PNG_OUTF_GA16_G16      &h04100000+PNGCP_16_16_SA
#define PNG_OUTF_GA16_GA8      &h04100000+PNGCP_16_8
#define PNG_OUTF_GA16_G8      &h04100100+PNGCP_16_8_SA

#define PNG_OUTF_TA8_TA8_BGRA   &h06080100+PNGCP_8_8_BGRA
#define PNG_OUTF_TA8_T8_BGR      &h06080100+PNGCP_8_8_BGR_SA
#define PNG_OUTF_TA16_TA16_BGRA   &h06100000+PNGCP_16_16_BGRA
#define PNG_OUTF_TA16_T16_BGR   &h06100000+PNGCP_16_16_BGR_SA
#define PNG_OUTF_TA16_TA8_BGRA   &h06100100+PNGCP_16_8_BGRA
#define PNG_OUTF_TA16_T8_BGR   &h06100100+PNGCP_16_8_BGR_SA

#define PNG_OUTF_AUTO            -1

'/******************************************************************************
'   Error codes
' ******************************************************************************/
' Couldn't open file
#define PNGLIB_ERR_OPENFILE               &h1000
#define PNGLIB_ERR_MEMALLOC               &h1001  ' Couldn't allocate memory
#define PNGLIB_ERR_ALREADY_LOADED         &h1002  ' Other data has already been loaded
#define PNGLIB_ERR_INVALIDPNG            &h2000  ' Corrupt or invalid PNG
#define PNGLIB_ERR_UNSUPPORTED            &h2001  ' PNG format not supported
#define PNGLIB_ERR_INVALIDFORMAT         &h2002  ' User error (!): Invalid format specified
#define PNGLIB_ERR_WRONGSTATE            &h2003  ' User error (!): Function call at the wrong time

#DEFINE PNGLIB_ERR_NOERROR               0      'No error has occurred
                                                    ' (e.g. decoding before loading data)
#define PNGLIB_ERR_NOPALETTE            &h2004  ' Palette requested for a non-paletted image
#define PNGLIB_ERR_INVALIDPARAMETER       &h2005  ' Invalid parameter used for function
#define PNGLIB_ERR_CREATEBITMAP            &h2006  ' Couldn't create bitmap
#define PNGLIB_ERR_FINDRESOURCE            &h3001  ' Couldn't find resource
#define PNGLIB_ERR_LOADRESOURCE            &h3002  ' Couldn't load resource


#DEFINE PNG_CT_GRAYSCALE               0
#DEFINE PNG_CT_RGB_TRIPLES               2
#DEFINE PNG_CT_PALETTE_INDEX            3
#DEFINE PNG_CT_GRAYSCALE_ALPHA            4
#DEFINE PNG_CT_RGB_ALPHA_QUADS            6

#DEFINE PNG_IM_NONE                 0
#DEFINE PNG_IM_ADAM7            1

#define PNG_PF_RGB         0   ' output: red byte, green byte, blue byte
#define PNG_PF_BGRX         1   ' output: blue byte, green byte, red byte, zero byte

#endif
counting_pine
Site Admin
Posts: 6172
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Bug in freebasic 1.05 compiler

Postby counting_pine » Jul 18, 2018 12:39

lassar wrote:There is a bug in the freebasic compiler.

There are 9 declare functions in pblib2.bi

And yet the compiler only complains about one of them.

Code: Select all

declare function PNG_LoadFile      stdcall alias "PNG_LoadFile"      (byval pPNGInfo as PNGINFO ptr, byval lpFileName as string) as integer


The compiler says "undefined reference to `PNG_LoadFile@16' "

The 'undefined reference' error happens at link-time, not compile-time. There might be a linker parameter that shows additional undefined references. Note that the linker error only happens if you use a function, not just declare it.

Think about it. the @16 says it needs 4 dwords for the parameters.(16 bytes)

And yet when you look at this function, It only need 2 dwords.(8 bytes)

I put pnglib2.a in notepad++, it mentions "_PNG_LoadFile@8": 2 dwords

This is a bug in freebasic 1.05 !
To be honest, I don't really like how you're assuming this is a bug in FB. Anyway...

This might be due to the behaviour change of ''byval as string', which happened since v0.20.
'byval as string' used to pass a zstring ptr ('byval as zstring ptr'), and now it makes a coy of the string and passes that by value.
If it pushes the whole string descriptor (I'm not sure if it does), then that would be 12 bytes, taking you to 16 total.
If you replace 'byval as string' with 'byval as zstring ptr' or 'byref as zstring', that might fix the problem.

This change could also be made in the library source code, for consistent behaviour across versions.
jj2007
Posts: 1233
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Undefined reference to `PNG_LoadFile@16'

Postby jj2007 » Jul 18, 2018 12:47

Code: Select all

declare function PNG_LoadFile      stdcall alias "PNG_LoadFile"      (byval pPNGInfo as PNGINFO ptr, byval lpFileName as string) as integer
That is a PNGINFO ptr passed by value, and the size of that is the size of one pointer. FreeBasic complains that it can't find the @16, for me that looks like a bug indeed. If you change that to byval pPNGInfo as any ptr, the code compiles but it won't run.
caseih
Posts: 1379
Joined: Feb 26, 2007 5:32

Re: Undefined reference to `PNG_LoadFile@16'

Postby caseih » Jul 18, 2018 12:57

Thanks for the complete example. This should help those familiar with the compiler's inner workings figure out what is going wrong.

I can confirm this appears to be a compiler bug in the gas emitter backend in fbc. -gen gcc does not appear to have this bug, although it cannot (with my installed version of gcc) parse your in-line assembly for whatever reason.
dodicat
Posts: 5938
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Undefined reference to `PNG_LoadFile@16'

Postby dodicat » Jul 18, 2018 15:56

Try this section.
Got rid of fblite.
Is it car.png ??
I have used car.png anyway, you might want to change it.

Code: Select all

 

#ifndef __png_library__

#define __png_library__
#inclib "pnglib2"


type PNGINFO field=1
   iWidth        as integer         ' Width of image
   iHeight        as integer         ' Height of image
   dwLastError     as integer         ' Last error code (PNGLIB_ERR_*)
   nColors        as integer         ' Number of palette entries, if present
   PNGColorType  as byte            ' Original PNG color type (PNG_CT_*)
   PNGBitDepth     as byte               ' Original PNG bit depth (bits/sample)
   PNGInterlaced as byte            ' Interlace method (PNG_IM_*)

   ' The following structure members are used internally
   ' by PNGlib. You should not rely in any way on these values,
   ' nor assume they will be present in later versions.
   ' They are included *only* to reserve space for them.

   lpPNGData     as byte ptr         ' pointer to data in PNG file
   lnPNGData     as integer         ' length of data pointed to by lpPNGData
   lpCurrent     as byte ptr         ' 'current pointer', used internally
   lpOutput     as byte ptr         ' pointer to decompressed (unfiltered) output data, used internally
   lnOutput     as integer         ' size of output data pointed to by lpOutput
   pPNGPalette   as byte ptr         ' pointer to data in PLTE chunk
   dwLoadType     as integer         ' type of data currently loaded (PNGI_LT_*)
   pHeader        as byte ptr         ' pointer to raw IHDR chunk *data* (&chunk+8)
   pIDAT        as byte ptr         ' pointer to start of first IDAT chunk
   curState     as integer         ' PNGI_STATE_*
    dummy as byte
end type

'' ========    end of declarations  ========




'print sizeof(pnginfo)

'/******************************************************************************
'   Function declararations
' ******************************************************************************/

   declare function PNG_Init           alias "PNG_Init"         ( byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_Cleanup        alias "PNG_Cleanup"      ( byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_LoadFile        alias "PNG_LoadFile"      ( byval pPNGInfo as PNGINFO ptr, byval  lpFileName as zstring ptr) as integer
   declare function PNG_LoadResource     alias "PNG_LoadResource"   ( byval pPNGInfo as PNGINFO ptr, byval  hInstance as integer, byval  lpResName as zstring ptr) as integer
   declare function PNG_LoadCustom     alias "PNG_LoadCustom"      ( byval pPNGInfo as PNGINFO ptr, byval  lpData as byte ptr, byval  lnData as integer) as integer
   declare function PNG_Decode        alias "PNG_Decode"         ( byval pPNGInfo as PNGINFO ptr) as integer
   declare function PNG_GetPalette     alias "PNG_GetPalette"      ( byval pPNGInfo as PNGINFO ptr, byval  lpOutput as any ptr,byval   dwFormat as integer) as integer
   declare function PNG_OutputRaw     alias "PNG_OutputRaw"      (byval  pPNGInfo as PNGINFO ptr, byval  lpDest as ubyte ptr, byval  dwFormat as integer) as integer
   declare function PNG_CreateBitmap     alias "PNG_CreateBitmap"   ( byval pPNGInfo as PNGINFO ptr, byval  hWndCompatible as integer, byval  dwFormat as integer,byval bDDB as integer) as integer

#endif



DECLARE sub LoadPNG(byval filename as zstring ptr)
DECLARE SUB ShowPng(Figure as zstring ptr)
DECLARE SUB LoadDirPng()


' Demo main part:

screenres 640,480,32',,&H01
    PRINT "Press any key to see car"
    SLEEP
    ShowPNG "car.png"
    DO:LOOP UNTIL INKEY  = ""
    DO:LOOP UNTIL INKEY  <> ""
    LoadDirPng
    SLEEP
    END



sub LoadPNG(byval Filename as zstring ptr)
   dim png_image AS PNGINFO
   dim as ubyte ptr palete,VideoPtr
dim as ubyte ptr PngSource

   print PNG_Init(@png_image)'=0 then return 0
   print PNG_LoadFile(@png_image, *Filename )'=0 then return 0
   print PNG_Decode(@png_image)'=0 then return 0

   palete=png_image.pPNGPalette
   PngSource=png_image.lpOutput'cast(ubyte ptr,png_image.lpOutput)


   print PNG_OutputRaw(@png_image,PngSource,0)
 
    VideoPtr = SCREENPTR
' It may be made in one cycle, but it will be slowly...

 var   NumberOfDwords = 640 * 480
   if Palete=0 then
        SCREENLOCK
      ASM
         MOV EBX,[NumberOfDwords]
         MOV ESI,[PngSource]
          MOV EDI,[VideoPtr]
          MOV ECX,[NumberOfDwords]
      DoItAgain:
            MOV EAX,0
            LODSB
            SHL EAX,8
            LODSB
            SHL EAX,8
            LODSB
            STOSD
        LOOP    DoItAgain
      END ASM
        SCREENUNLOCK
    else
        SCREENLOCK
      ASM
         MOV EBX,[NumberOfDwords]
         MOV ESI,[PngSource]
          MOV EDI, [VideoPtr]
          MOV ECX,[NumberOfDwords]
      DoItAgain2:
          MOV EAX,0
          LODSB
         MOV EBX,EAX
         ADD EAX,EBX
         ADD EAX,EBX
            PUSH ESI
            MOV ESI,[palete]
            ADD ESI, EAX
            MOV EAX,0
            LODSB
            SHL EAX,8
            LODSB
            SHL EAX,8
            LODSB
            STOSD
            POP ESI
      LOOP DoItAgain2
      END ASM
        SCREENUNLOCK
    end if

   PNG_Cleanup(@png_image)

end sub


SUB ShowPng(PngFile as zstring ptr)

    LoadPNG PngFile

END SUB


SUB LoadDirPng()
   var Fn  = DIR ("DATA\*.PNG")
    WHILE Fn  <> ""
     var   FilePath  = CURDIR  + "\DATA\" +  Fn
        ShowPng FilePath
        Fn  = DIR
    WEND
END SUB


 

I have put together some stuff for a gdi library.
I shall pop it in mediafire later.
windows only of course.
jj2007
Posts: 1233
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Undefined reference to `PNG_LoadFile@16'

Postby jj2007 » Jul 18, 2018 16:55

dodicat wrote:Is it car.png ??
No, the file is OK, it displays fine with another library. In case you got it running: Can you post the exe somewhere? I'd like to see how it works in the debugger. So far I have not seen a successful one, even your latest code passes Init and Load but then throws an exception. Frustrating.
dkl
Site Admin
Posts: 3209
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Undefined reference to `PNG_LoadFile@16'

Postby dkl » Jul 18, 2018 17:45

As counting_pine said, since the library has _PNG_LoadLibrary@8, not @16, it's probably BYVAL AS STRING from old FB versions where it was broken and worked like BYREF AS ZSTRING. The declaration can be changed to BYREF AS ZSTRING or BYVAL AS ZSTRING PTR now and then new FB versions can use the old library.

Otherwise if you really want BYVAL AS STRING then the library must be recompiled with the latest FB version so the symbol name is fixed (unfortunately FB isn't backwards compatible here).

Good job finding the inconsistency between -gen gas and -gen gcc for this case; new ticket: https://sourceforge.net/p/fbc/bugs/890/
dodicat
Posts: 5938
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Undefined reference to `PNG_LoadFile@16'

Postby dodicat » Jul 18, 2018 18:26

jj2007 wrote:
dodicat wrote:Is it car.png ??
No, the file is OK, it displays fine with another library. In case you got it running: Can you post the exe somewhere? I'd like to see how it works in the debugger. So far I have not seen a successful one, even your latest code passes Init and Load but then throws an exception. Frustrating.


Remember that your car.png must be 640 by 480.

Anyway I get a poor png here with some local images.

i'll get the gdi code tidy and post via mediafire.
Now i take the dog for a walk.
caseih
Posts: 1379
Joined: Feb 26, 2007 5:32

Re: Undefined reference to `PNG_LoadFile@16'

Postby caseih » Jul 18, 2018 19:27

So if I interpret what was written here and in the bug report correctly, it's the GCC emitter that has the bug in it, correct? The GAS emitter is doing the right thing. The bug is not in FBC but in Lassar's declaration in the .bi file. I feel sheepish for not seeing that before. pnglib2 is a C-based library, so it's going to be using zstring ptrs, not FB strings.

Lassar, in the future please be careful about declaring you've found bugs in the compiler. One's own code is always the first suspect, even when it used to compile before. That's not to say the compiler doesn't have bugs in it (although it appears you've inadvertently uncovered a compiler bug, just not the one you thought it was).
dodicat
Posts: 5938
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Undefined reference to `PNG_LoadFile@16'

Postby dodicat » Jul 18, 2018 21:35

Here is gdi code plus library file.
Thanks to member UEZ for much of the gdi work.
Compiled here with -gen gas.
(The only sure way)
http://www.mediafire.com/file/88h09094uew4yz2/images.zip

Windows only.
Should handle 8 bit png/jpeg/bmp ... also.
jj2007
Posts: 1233
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Undefined reference to `PNG_LoadFile@16'

Postby jj2007 » Jul 19, 2018 0:58

dodicat wrote:Remember that your car.png must be 640 by 480.
Oops, I had not realised that: Your code (and only your code) works with a 640x480 car.png, congrats!
dodicat
Posts: 5938
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Undefined reference to `PNG_LoadFile@16'

Postby dodicat » Jul 19, 2018 17:33

If anyone has tested the GDI library I linked above.
For #lang "fblite"
I had to include byval on all the parameters.
So, I suppose I should have used byval anyway for lang fb

Here are the declarations suitable for fb and fblite
(I also tweaked the sub truck to suit fblite

Code: Select all

 
#inclib "images"

#lang "fblite"
declare Function ImageSave( Filename as wString,byval Image As any Ptr,byval JPGQual as ULong = 80) as Boolean
declare Function ImageLoad(Filename as String,byref i as any ptr=0) as long
declare sub getsize(Filename as string,byref w as single,byref h as single)
declare Function resize(byval im As Any Ptr,byval Wdth As Single,byval Hght As Single,byval dx As Long=0,byval dy As Long=0) As Any Ptr

'usage
'imageload/imagesave/getsize any of ---  bmp jpeg gif tiff tif png  -----
'resize -- resize a image from freebasic to wdth hght

'=======   demo =============

screen 20,32
color ,rgb(200,200,200)
cls


declare function truck(as any ptr=imagecreate(500,500)) as any ptr


dim as any ptr  image=(resize(truck,640,480))

print imagesave("truck.png",image)

dim as single w,h

getsize "truck.png",w,h

dim as any ptr newimage=imagecreate(w,h)

print imageload("truck.png",newimage)

put(20,20),newimage,trans

locate 35,10
print "Press a key"
sleep
imageLoad("Bob.jpg")                            'straight to the screen with a .jpg

imagedestroy image
imagedestroy newimage



function truck(im as any ptr) as any ptr
    #macro thickline(x1,y1,x2,y2,thickness,colour,i)
 h=Sqr((x2-x1)^2+(y2-y1)^2)
 s=(y1-y2)/h
 c=(x2-x1)/h
For yp =-thickness/2 To thickness/2 Step 1/(thickness)
    Line im,(x1+(s*yp),y1+(c*yp))-(x2+(s*yp),y2+(c*yp)),colour
Next yp
#endmacro
dim as double h,s,c,yp
circle im,(220,185),25,rgb(55,55,0),,,2,f
circle im,(220,150),15,rgb(100,65,0),,,.8,f
thickline(220,165,180,200,5,rgb(55,55,0),im)'a
thickline(50,260,450,260,6,rgb(50,50,150),im)
thickline(65,260,65,200,6,rgb(50,50,150),im)'up
thickline(65,200,165,190,6,rgb(50,50,150),im)'bon
thickline(165,190,250,190,6,rgb(50,50,150),im)'lwin
thickline(165,190,175,130,3,rgb(10,10,10),im)'fw
thickline(175,130,250,130,6,rgb(10,10,10),im)'rf
circle im,(200,115),15,rgb(255,155,0),,,.5,f

thickline(250,130,250,220,3,rgb(50,50,150),im)'bcab
thickline(250,220,420,220,8,rgb(50,50,150),im)'bbase
thickline(420,220,420,260,8,rgb(50,50,150),im)'aft
thickline(265,100,265,200,10,rgb(50,50,50),im)'upright
thickline(265,110,450,100,2,rgb(50,50,50),im)'wire
paint im,(300,240),rgb(50,50,150),rgb(50,50,150)
thickline(50,260,450,260,6,rgb(100,100,200),im)

circle im,(265,205),12,rgb(20,20,20),,,,f
thickline(265,205,450,100,10,rgb(0,0,0),im)
thickline(450,100,450,230,5,rgb(0,0,0),im)'hk
circle im,(450,210),20,1,2.9
thickline(50,260,70,260,12,rgb(220,220,220),im)'fb
thickline(430,260,450,260,12,rgb(210,210,210),im)'ab
circle im,(130,270),30,rgb(50,50,50),,,,f
circle im,(370,270),30,rgb(50,50,50),,,,f
circle im,(130,270),20,rgb(150,150,150),,,,f
circle im,(370,270),20,rgb(150,150,150),,,,f
return im
end function

sleep 


For fblite the static library must be used (compiled with fb)
fblite cannot
#Include "win/gdiplus.bi"

because of the constructors e.t.c. therein.
UEZ
Posts: 336
Joined: May 05, 2017 19:59
Location: Germany

Re: Undefined reference to `PNG_LoadFile@16'

Postby UEZ » Nov 01, 2018 21:03

dodicat wrote:Here are .png file load/save using GDI.
Mainly coded by UEZ originally.
i cannot get it to work in 64 bits.
But the 32 bit compiler works OK.
If you have problems try pset on line 28
and
point on line 55
by uncommenting

Code: Select all

 

#if sizeof(integer)=8
#include "windows.bi"
''declare sub CLSIDFromString alias "CLSIDFromString"(as wstring,as _guid ptr) ''for 64 bits but doesn't work
#endif
#Include  "win/gdiplus.bi"

#include "file.bi"

Function ImageLoad(Picture as String,byref i as any ptr) as long
    #define putpixel(_x,_y,colour)    *cptr(ulong ptr,row+ (_y)*pitch+ (_x) shl 2)  =(colour)
    static as integer pitch
    static as any ptr row
     Imageinfo i,,,,pitch,row
   Dim As uinteger TMP
   GDIPLUS.GdiplusStartup(@TMP,@type<GDIPLUS.GDIPLUSSTARTUPINPUT>(1),0)
   Dim as any Ptr Img
   if GDIPLUS.GdipLoadImageFromFile(Picture,@Img)>0 then return 0
   Dim As Single w,h
   GDIPLUS.GdipGetImageDimension(Img,@w,@h)
   if w*h=0 then  return 0
   Dim As GDIPLUS.BitmapData Pdata
   Dim As Rect R=Type(0,0,w-1,h-1)
   GDIPLUS.GdipBitmapLockBits(Img,Cast(Any Ptr,@R),GDIPLUS.ImageLockModeRead,PixelFormat32bppARGB,@Pdata)
   For y as long = 0 To h-1
      For x as long = 0 To w-1
          ' pset i,(x,y),Cast(ulong Ptr,Pdata.Scan0)[y*w+x]
        putpixel(x,y,(Cast(ulong Ptr,Pdata.Scan0)[y*w+x]))
      Next
   Next
return w*h
End Function

Function ImageSave( Filename as WString,Image As any Ptr, JPGQual as ULong = 80) as Boolean
    #define _getpixel(_x,_y)           *Cptr(Ulong Ptr,pixdata + (_y)*pitch + (_x) Shl 2)
   Dim as Integer w, h, bypp, pitch
   Dim pixdata As Any Ptr
   If 0 <> ImageInfo(Image, w, h, bypp, pitch, pixdata) Then Return False
   
   Dim GDIPlusStartupInput As GDIPLUS.GDIPLUSSTARTUPINPUT
   Dim As ULONG_PTR GDIPlusToken
   GDIPlusStartupInput.GdiplusVersion = 1   
   If (GDIPLUS.GdiplusStartup(@GDIPlusToken, @GDIPlusStartupInput, NULL) <> 0) Then Return 0
   Dim as Uinteger  x, y, RowOffset
   Dim As Any Ptr hBitmap
   Dim As GDIPLUS.BitmapData tBitmapData
   Dim As Rect tRect = Type(0, 0, w - 1, h - 1)
   GDIPLUS.GdipCreateBitmapFromScan0(w, h, 0, PixelFormat32bppARGB, 0, @hBitmap)
   GDIPLUS.GdipBitmapLockBits(hBitmap, Cast(Any Ptr, @tRect), GDIPLUS.ImageLockModeWrite, PixelFormat32bppARGB, @tBitmapData)
   For y = 0 to h - 1
      RowOffset = y * w
      for x = 0 to w - 1
           Cast(Integer Ptr, tBitmapData.Scan0)[RowOffset + x] = &hFF000000 + _getpixel(x, y)
         'Cast(Integer Ptr, tBitmapData.Scan0)[RowOffset + x] = &hFF000000 + point(x, y, Image)
      Next     
   Next
   GDIPLUS.GdipBitmapUnlockBits(hBitmap, @tBitmapData)
   
   Dim as Byte iErr = 0

   Dim as UInteger count, size
   GDIPLUS.GdipGetImageEncodersSize(@count, @size)
   Dim As GDIPLUS.ImageCodecInfo Ptr pImageCodecInfo, Clsid
   pImageCodecInfo = Allocate(size)
   GDIPLUS.GdipGetImageEncoders(count, size, pImageCodecInfo)
   
   For i as ulong = 0 to count
      If *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/bmp" and Right(Filename, 4) = ".bmp" Then
         If (GDIPLUS.GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      Elseif *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/jpeg" and (Right(Filename, 4) = ".jpg" or Right(Filename, 5) = ".jpeg") Then
         'If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1   
         JPGQual = IIf(JPGQual < 0, 0, IIf(JPGQual > 100, 100, JPGQual))
         Dim tParams As GDIPLUS.EncoderParameters
         Dim EncoderQuality As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
         tParams.Count = 1
    CLSIDFromString(Wstr(EncoderQuality), @tParams.Parameter(0).GUID) 'ERROR on 64 bits
   
         With tParams.Parameter(0)
            .NumberOfValues = 1
            .Type = GDIPLUS.EncoderParameterValueTypeLong
            .Value = VarPtr(JPGQual)
         End With
         If GDIPLUS.GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, @tParams) <> 0 Then iErr += 1         
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/gif" and Right(Filename, 4) = ".gif" Then
        If (GDIPLUS.GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/tiff" and (Right(Filename, 4) = ".tif" or Right(Filename, 5) = ".tiff") Then
        If (GDIPLUS.GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/png" and Right(Filename, 4) = ".png" Then
        If (GDIPLUS.GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1     
      Elseif  *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/ico" and Right(Filename, 4) = ".ico" Then
         iErr += 1
      End if
   Next

   Deallocate(pImageCodecInfo)

   GDIPLUS.GdipDisposeImage(hBitmap)
   GDIPLUS.GdiplusShutdown(GDIPlusToken)
   If iErr > 0 Then Return False

   Return True
End function

sub getsize(picture as string,byref w as single,byref h as single) 'unused
    Dim As uinteger TMP
   GDIPLUS.GdiplusStartup(@TMP,@type<GDIPLUS.GDIPLUSSTARTUPINPUT>(1),0)
   Dim as any Ptr Img
   if GDIPLUS.GdipLoadImageFromFile(Picture,@Img)>0 then exit sub
   GDIPLUS.GdipGetImageDimension(Img,@w,@h)
end sub


screen 20,32

dim as any ptr im=imagecreate(500,500,rgb(0,0,150))

for n as long=0 to 100
    circle im,(rnd*500,rnd*500),5+rnd*15,rgb(rnd*255,rnd*255,rnd*255),,,,f
next

imagesave("circles.png",im)
if fileexists("circles.png") then print "OK" else print "Failed to save .png file"
dim as single w,h

getsize("circles.png",w,h)
print "width","height"
print w,h

dim as any ptr im2=imagecreate(w,h)
ImageLoad("circles.png",im2)

put(100,100),im2
sleep
imagedestroy im
imagedestroy im2


 


To get it work also on x64 just change the line in function
For i as ulong = 0 to count to For i as ulong = 0 to count - 1

This works:

Code: Select all

Function _GDIPlus_ImageSaveToFile(hBitmap As any Ptr, Filename as WString, JPGQual as ULong = 85) as Boolean
   Dim as Single iW, iH
   Dim As Long iStatus
   iStatus = GdipGetImageDimension(hBitmap, @iW, @iH)
   If iStatus <> 0 Then Return 0
   
   Dim as Byte iErr = 0

   Dim as ulong count, size
   GdipGetImageEncodersSize(@count, @size)
   
   dim as CLSID clsid
   Dim As ImageCodecInfo Ptr pImageCodecInfo
   pImageCodecInfo = Allocate(size)
   GdipGetImageEncoders(count, size, pImageCodecInfo)

   For i as ulong = 0 to count - 1
      If *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/bmp" and Right(Filename, 4) = ".bmp" Then
         If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      Elseif *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/jpeg" and (Right(Filename, 4) = ".jpg" or Right(Filename, 5) = ".jpeg") Then
         'If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1   
         JPGQual = IIf(JPGQual < 0, 0, IIf(JPGQual > 100, 100, JPGQual))
         Dim tParams As EncoderParameters
         Dim EncoderQuality As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
         tParams.Count = 1
         CLSIDFromString(Wstr(EncoderQuality), @tParams.Parameter(0).GUID)
         With tParams.Parameter(0)
            .NumberOfValues = 1
            .Type = EncoderParameterValueTypeLong
            .Value = VarPtr(JPGQual)
         End With
         If GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, @tParams) <> 0 Then iErr += 1         
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/gif" and Right(Filename, 4) = ".gif" Then
         If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/tiff" and (Right(Filename, 4) = ".tif" or Right(Filename, 5) = ".tiff") Then
         If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1
      ElseIf *cast(wstring ptr, pImageCodecInfo[i].MimeType) = "image/png" and Right(Filename, 4) = ".png" Then
         If (GdipSaveImageToFile(hBitmap, WStr(Filename), @pImageCodecInfo[i].Clsid, NULL) <> 0) Then iErr += 1     
      Else
         iErr += 1
      End if
   Next

   Deallocate(pImageCodecInfo)

   If iErr > 0 Then Return False

   Return True
End Function

Return to “General”

Who is online

Users browsing this forum: No registered users and 17 guests