Code archives/User Libs/FreeImage Module for B3D/B+

This code has been declared by its author to be Public Domain code.

Download source code

FreeImage Module for B3D/B+ by markcw
(Posted 21 years ago)
The decls have been updated to FreeImage.dll 3.10.0.

The FreeImage.dll can be found inside the binary distribution: http://freeimage.sourceforge.net/

FreeImage is an open source project and is free to license (use the FreeImage licence version).

The module can now be downloaded here (Freeimage.dll not included): http://blitzmirror.angelfire.com/

Copy/paste this code and save it as "freeimage.bb".
;FreeImage Module for B3D/B+
;Author: markcw, edited 29 Nov 08
;Site: freeimage.sourceforge.net/

;Load and save image functions

Function FiLoadImage(filename$)
 ;Loads an image from filename$
 ;Returns an image or False if fails
 ;Uses FiLoad and FiRead

 Local dib, image
 dib = FiLoad(filename$)
 image = FiRead(dib)
 FreeImage_Unload(dib)
 Return image

End Function

Function FiSaveImage(image, filename$)
 ;Saves an image as filename$
 ;Returns True if succeeds or False if fails
 ;Uses FiWrite and FiSave

 Local dib, bool
 dib = FiWrite(image)
 bool = FiSave(dib, filename$)
 FreeImage_Unload(dib)
 Return bool

End Function

Function FiLoad(filename$)
 ;Loads a FreeImage bitmap from filename$
 ;Returns a FreeImage bitmap or False if fails

 Local fif, dib
 fif = FreeImage_GetFIFFromFilename(filename$) ;Format from extension
 If fif >= 0 ;Format is valid
  dib = FreeImage_Load(fif, filename$, 0)
 EndIf
 Return dib

End Function

Function FiRead(dib)
 ;Reads a FreeImage bitmap and writes an image
 ;Returns an image or False if fails

 Local dib24, pixel, width, height, image, buffer, ix, iy

 dib24 = FreeImage_ConvertTo24Bits(dib) ;Copy to 24 bit, no palette
 If dib24 = 0 Then Return 0 ;Unknown format
 pixel = CreateBank(4) ;Temp bank
 width = FreeImage_GetWidth(dib)
 height = FreeImage_GetHeight(dib)
 image = CreateImage(width, height)
 buffer = GraphicsBuffer()

 LockBuffer(ImageBuffer(image))
 For iy = 0 To height - 1
  For ix = 0 To width - 1
   FreeImage_GetPixelColor(dib24, ix, height - 1 - iy, pixel) ;Invert
   WritePixelFast ix, iy, PeekInt(pixel, 0), ImageBuffer(image)
  Next
 Next
 UnlockBuffer(ImageBuffer(image))

 SetBuffer buffer
 FreeImage_Unload(dib24)
 FreeBank pixel
 Return image

End Function

Function FiSave(dib, filename$)
 ;Saves a FreeImage bitmap as filename$
 ;Returns True if succeeds or False if fails

 Local fif, bpp, dib8, dib24, bool

 If dib = 0 Then Return 0 ;No image
 fif = FreeImage_GetFIFFromFilename(filename$) ;Format from extension
 bpp = FreeImage_GetBPP(dib) ;bpp will be one of 1/4/8/16/24/32
 dib8 = dib ;8 bit or other, variable passed to FreeImage_Save
 dib24 = dib ;24 bit

 If fif >= 0 ;Format is valid
  If fif = 11 ;Check pgm format, pgm=11/pgmraw=12
   dib8 = FreeImage_ConvertToGreyscale(dib) ;8 bit greyscale
  ElseIf fif = 25 ;Gif format, gif=25
   If bpp <> 24 ;Dib not 24 bits
    dib24 = FreeImage_ConvertTo24Bits(dib)
   EndIf
   dib8 = FreeImage_ColorQuantize(dib24, 0) ;8 bit paletted
   If dib24 <> dib ;24 bit conversion was required
    FreeImage_Unload(dib24)
   EndIf
  EndIf
  bool = FreeImage_Save(fif, dib8, filename$, 0)
  If dib8 <> dib ;8 bit conversion was required
   FreeImage_Unload(dib8)
  EndIf
 EndIf

 Return bool

End Function

Function FiWrite(image)
 ;Reads an image and writes a FreeImage bitmap
 ;Returns a FreeImage bitmap or False if fails

 Local pixel, width, height, dib, buffer, ix, iy

 If image = 0 Then Return 0 ;No image
 pixel = CreateBank(4) ;Temp bank
 width = ImageWidth(image)
 height = ImageHeight(image)
 dib = FreeImage_Allocate(width, height, 24, $ff0000, $00ff00, $0000ff)
 buffer = GraphicsBuffer()

 LockBuffer(ImageBuffer(image))
 For iy = 0 To height - 1
  For ix = 0 To width - 1
   PokeInt pixel, 0, ReadPixelFast(ix, iy, ImageBuffer(image))
   FreeImage_SetPixelColor(dib, ix, height - 1 - iy, pixel) ;Invert
  Next
 Next
 UnlockBuffer(ImageBuffer(image))

 SetBuffer buffer
 FreeBank pixel
 Return dib

End Function

Function FiUnload(dib)
 ;Frees a FreeImage bitmap, a wrapper function
 ;Returns nothing

 FreeImage_Unload(dib)

End Function

;Load and save anim image functions

Function FiLoadAnimImage(filename$, index = 0, frames = 0)
 ;Loads an anim image from a FreeImage multipage bitmap
 ;index -> first frame, 0=first, frames -> number of frames, 0=all
 ;Returns an image or False if fails
 ;Uses FiOpenAnim

 Local dib, count, pixel, page, width, height
 Local image, graphic, buffer, dib24, ix, iy, dst

 dib = FiOpenAnim(filename$, 1) ;Load read-only
 If dib = 0 Then Return 0 ;No dib
 count = FreeImage_GetPageCount(dib) ;Number of frames
 If index < 0 Or index > count - 1 Then index = count - 1
 If frames < 1 Or frames > count Then frames = count
 If frames + index > count Then frames = count - index

 pixel = CreateBank(4)
 page = FreeImage_LockPage(dib, 0) ;Lock first page
 width = FreeImage_GetWidth(page) ;Get the width/height
 height = FreeImage_GetHeight(page)
 FreeImage_UnlockPage(dib, page, 0) ;Unlock
 image = CreateImage(width, height, frames)
 graphic = CreateImage(width, height)
 buffer = GraphicsBuffer()

 For count = 0 To index + frames - 1
  page = FreeImage_LockPage(dib, count) ;Lock next page
  dib24 = FreeImage_ConvertTo24Bits(page) ;Copy to 24 bits, no palette
  FreeImage_UnlockPage(dib, page, 0) ;Unlock

  LockBuffer(ImageBuffer(graphic))
  For iy = 0 To height - 1
   For ix = 0 To width - 1
    FreeImage_GetPixelColor(dib24, ix, height - 1 - iy, pixel) ;Invert
    WritePixelFast ix, iy, PeekInt(pixel, 0), ImageBuffer(graphic)
   Next
  Next
  UnlockBuffer(ImageBuffer(graphic))

  If count - index >= 0 ;Frame is valid
   dst = ImageBuffer(image, count - index) ;Copy graphic to frame
   CopyRect 0, 0, width, height, 0, 0, ImageBuffer(graphic), dst
  EndIf
  FreeImage_Unload(dib24) ;Free dib
 Next

 SetBuffer buffer
 FreeImage graphic
 FreeBank pixel
 FreeImage_CloseMultiBitmap(dib, 0)
 Return image

End Function

Function FiSaveAnimImage(image, filename$, frames, index = 0)
 ;Saves an anim image as filename$
 ;frames -> number of frames, index -> first frame, 0=first
 ;Returns True if succeeds or False if fails
 ;Uses FiOpenAnim

 Local dib, fif, pixel, width, height, dib24
 Local buffer, count, ix, iy, page

 If image = 0 Then Return 0 ;No image
 dib = FiOpenAnim(filename$, 2, 0) ;2=create new
 fif = FreeImage_GetFIFFromFilename(filename$) ;format from extension
 frames = frames + index
 If frames < 1 Then frames = 1 ;Limit
 If index < 0 Or index > frames - 1 Then index = frames - 1

 pixel = CreateBank(4) ;Temp bank
 width = ImageWidth(image)
 height = ImageHeight(image)
 dib24 = FreeImage_Allocate(width, height, 24, $ff0000, $00ff00, $0000ff)
 buffer = GraphicsBuffer()

 For count = index To frames - 1
  LockBuffer(ImageBuffer(image, count))
  For iy = 0 To height - 1
   For ix = 0 To width - 1
    PokeInt pixel, 0, ReadPixelFast(ix, iy, ImageBuffer(image, count))
    FreeImage_SetPixelColor(dib24, ix, height - 1 - iy, pixel) ;Invert
   Next
  Next
  UnlockBuffer(ImageBuffer(image, count))

  If fif = 25 ;Gif format
   page = FreeImage_ColorQuantize(dib24, 0) ;8 bit palette
  Else ;Other format, ico=1/tif=18
   page = FreeImage_ConvertTo24Bits(dib24) ;24 bits
  EndIf
  FreeImage_AppendPage(dib, page) ;Add next page
  FreeImage_Unload(page)
 Next

 SetBuffer buffer
 FreeBank pixel
 FreeImage_Unload(dib24)
 FreeImage_CloseMultiBitmap(dib, 0)
 Return 1

End Function

Function FiAnimFrames(filename$, index = 0, frames = 0)
 ;Returns the number of frames in a FreeImage multipage bitmap
 ;index -> first frame, 0=first, frames -> number of frames, 0=all
 ;Uses FiOpenAnim

 Local dib, count
 dib = FiOpenAnim(filename$, 1) ;Load as read-only
 count = FreeImage_GetPageCount(dib)
 If index < 0 Or index > count - 1 Then index = count - 1
 If frames < 1 Or frames > count Then frames = count
 If frames + index > count Then frames = count - index
 FreeImage_CloseMultiBitmap(dib, 0)
 Return frames

End Function

Function FiOpenAnim(filename$, opentype = 0, flags = 0)
 ;Opens a FreeImage multipage bitmap from filename$
 ;opentype -> 0=open read/write, 1=open read-only, 2=create new
 ;Returns a FreeImage multipage bitmap or False if fails

 Local fif, dib, isnew, isread
 If opentype = 1 Then isread = 1
 If opentype = 2 Then isnew = 1
 fif = FreeImage_GetFIFFromFilename(filename$) ;Format from extension
 If fif >= 0 ;Format is valid
  dib = FreeImage_OpenMultiBitmap(fif, filename$, isnew, isread, 0, flags)
 EndIf
 Return dib

End Function

Function FiCloseAnim(dib, flags = 0)
 ;Closes a FreeImage multipage bitmap, a wrapper function
 ;Returns nothing

 FreeImage_CloseMultiBitmap(dib, flags)

End Function

;Image manipulation functions

Function FiRescale(dib, scale, filter = 0)
 ;Rescales a FreeImage bitmap
 ;scale -> scale as percentage, filter -> scale algorithm 0..5
 ;Returns a rescaled FreeImage bitmap or False if fails

 Local width, height
 width = (scale * FreeImage_GetWidth(dib)) / 100
 height = (scale * FreeImage_GetHeight(dib)) / 100
 Return FreeImage_Rescale(dib, width, height, filter)

End Function

Function FiRotateClassic(dib, angle#)
 ;Rotates a FreeImage bitmap by a degree, 0..360
 ;Returns a rotated FreeImage bitmap

 Local dlo, dhi
 angle# = -angle# ;Invert angle
 dlo = FiFloatToDouble(angle#, 0)
 dhi = FiFloatToDouble(angle#, 1)
 Return FreeImage_RotateClassic(dib, dlo, dhi)

End Function

Function FiRotateClassicEx(dib, angle#, bgcolor = 0)
 ;Rotates a FreeImage bitmap by a degree, 0..360
 ;bgcolor -> RGB background color
 ;Returns a rotated FreeImage bitmap
 ;From FreeImage source by Hervé Drolon
 ;NB: sub-functions need 16/24/32 bits per pixel

 Local bpp, hsrc, hdst
 bpp = FreeImage_GetBPP(dib)
 hsrc = dib ;Init source
 If bpp < 16 ;Image is 1/4/8 bits per pixel
  hsrc = FreeImage_ConvertTo24Bits(dib) ;Copy to 24 bits
 EndIf
 hdst = FiRotateAny(hsrc, angle#, bgcolor)
 If hsrc <> dib ;Conversion required
  FreeImage_Unload(hsrc) ;Free from memory
 EndIf
 Return hdst

End Function

Function FiAdjustGamma(dib, gamma#)
 ;Adjust gamma correction on a 8/24/32-bit FreeImage bitmap, 0.1..10.0
 ;A value of 1.0 leaves the image alone
 ;less than one darkens it, and greater than one lightens it
 ;Returns True if succeeds or False if fails

 Local dlo, dhi
 dlo = FiFloatToDouble(gamma#, 0)
 dhi = FiFloatToDouble(gamma#, 1)
 Return FreeImage_AdjustGamma(dib, dlo, dhi)

End Function

Function FiAdjustBrightness(dib, brightness#)
 ;Adjusts the brightness of a 8/24/32-bit FreeImage bitmap, -100..100
 ;A value 0 means no change, less than 0 will make the image darker
 ;and greater than 0 will make the image brighter
 ;Note: FreeImage_AdjustBrightness is actually an intensity algorithm
 ;Adapted from FreeImage source by Hervé Drolon

 Local plut, i, value#, bool
 plut = CreateBank(256) ;Lookup table
 If brightness# > 100 Then brightness# = 100 ;-100..100
 If brightness# < -100 Then brightness# = -100
 For i = 0 To 255 ;Build the lut
  value# = i + (255 * brightness# / 100) ;Calc brightness
  If value# > 255 Then value# = 255 ;value 0..255
  If value# < 0 Then value# = 0
  PokeByte plut, i, Floor(value# + 0.5)
 Next
 bool = FreeImage_AdjustCurve(dib, plut, 0) ;Apply lut
 FreeBank plut ;Free from memory
 Return bool

End Function

Function FiAdjustIntensity(dib, intensity#)
 ;Adjusts the intensity of a 8/24/32-bit FreeImage bitmap, -100..100
 ;A value 0 means no change, less than 0 will decrease the contrast
 ;and greater than 0 will increase the contrast
 ;Note: FreeImage_AdjustBrightness is actually an intensity algorithm
 ;From FreeImage source by Hervé Drolon

 Local plut, i, value#, bool
 plut = CreateBank(256) ;Lookup table
 If intensity# > 100 Then intensity# = 100 ;-100..100
 If intensity# < -100 Then intensity# = -100
 For i = 0 To 255 ;Build the lut
  value# = i * (100 + intensity#) / 100 ;Calc intensity
  If value# > 255 Then value# = 255 ;value 0..255
  If value# < 0 Then value# = 0
  PokeByte plut, i, Floor(value# + 0.5)
 Next
 bool = FreeImage_AdjustCurve(dib, plut, 0) ;Apply lut
 FreeBank plut ;Free from memory
 Return bool

End Function

Function FiAdjustContrast(dib, contrast#)
 ;Adjusts the contrast of a 8/24/32-bit FreeImage bitmap, -100..100
 ;A value 0 means no change, less than 0 will decrease the contrast
 ;and greater than 0 will increase the contrast
 ;Returns True if succeeds or False if fails

 Local dlo, dhi
 dlo = FiFloatToDouble(contrast#, 0)

 dhi = FiFloatToDouble(contrast#, 1)
 Return FreeImage_AdjustContrast(dib, dlo, dhi)

End Function

;Information functions

Function FiGetWidth(dib)
 ;Returns the width of a FreeImage bitmap, a wrapper function

 Return FreeImage_GetWidth(dib) ;Get bitmap info

End Function

Function FiGetHeight(dib)
 ;Returns the height of a FreeImage bitmap, a wrapper function

 Return FreeImage_GetHeight(dib)

End Function

Function FiGetBPP(dib)
 ;Returns the bits per pixel of a FreeImage bitmap, a wrapper function

 Return FreeImage_GetBPP(dib)

End Function

;Clipboard functions

Function FiCopyToClipboard(dib)
 ;Copies a FreeImage bitmap to the clipboard
 ;Returns True is succeeds or False if fails
 ;Uses User32.dll And Kernel32.dll
 ;From: Copying a DIB to the clipboard, by John Simmons
 ;Site: www.codeproject.com

 Local phdr, ppal, pbits, sdib, sbits, bank, shdr, spal, hmem

 phdr = FreeImage_GetInfoHeader(dib) ;Pointer to info header
 ppal = FreeImage_GetPalette(dib) ;Pointer to palette
 pbits = FreeImage_GetBits(dib) ;Pointer to bits

 ;Calc bits, DWORD-aligned scanline (Pitch) * Height
 sbits = FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)
 sdib = FreeImage_GetDIBSize(dib) ;total size
 bank = CreateBank(sdib) ;Bank to store dib
 FiApiMemoryToBank(bank, phdr, 40) ;Move info header to bank
 shdr = PeekInt(bank, 0) ;biSize

 ;Calc palette, FreeImage bitmaps use the BITMAPINFO struct
 spal = PeekInt(bank, 32) ;biClrUsed
 If Not spal
  If PeekShort(bank, 14) <> 24 ;No color table for 24-bit
   spal = 1 Shl PeekShort(bank, 14) ;biBitCount, colors=2/16/256
  EndIf
 EndIf
 spal = spal * 4 ;sizeof(RGBQUAD)

 ;Move bits, palette and header separately for proper alignment
 FiApiMemoryToBank(bank, pbits, sbits) ;Move bits to bank
 CopyBank bank, 0, bank, shdr + spal, sbits ;Move bits up
 FiApiMemoryToBank(bank, ppal, spal) ;Move palette to bank
 CopyBank bank, 0, bank, shdr, spal ;Move palette up
 FiApiMemoryToBank(bank, phdr, shdr) ;Move info header to bank


 ;Alloc memory block to store our dib
 hmem = FiApiGlobalAlloc(66, sdib) ;GHND=66, MOVEABLE=2|ZEROINIT=64
 If Not hmem ;Major bummer if we couldn't get memory block
  FreeBank bank
  Return False ;Fail
 EndIf

 phdr = FiApiGlobalLock(hmem) ;Lock memory and get pointer to it
 FiApiBankToMemory(phdr, bank, sdib) ;Move dib to memory
 FiApiGlobalUnlock(hmem) ;Unlock the dib

 ;Send the dib to the clipboard
 If FiApiOpenClipboard(0) ;hwnd
  FiApiEmptyClipboard() ;Free last data
  FiApiSetClipboardData(8, hmem) ;CF_DIB=8, hdata[bitmap]
  FiApiCloseClipboard()
 EndIf

 FreeBank bank
 Return True ;Success

End Function

Function FiPasteFromClipboard()
 ;Pastes the clipboard to a new FreeImage bitmap
 ;Returns a FreeImage bitmap or dummy bitmap if fails
 ;Uses User32.dll And Kernel32.dll
 ;From: Copying a DIB to the clipboard, by John Simmons
 ;Site: www.codeproject.com

 Local hmem, dib, phdr, bank, shdr, spal, bw, bh
 Local bpp, sbits, sdib, ppal, pbits

 ;Receive the bitmap from the clipboard as a dib
 If FiApiOpenClipboard(0) ;hwnd
  hmem = FiApiGetClipboardData(8) ;CF_DIB=8
  FiApiCloseClipboard()
 EndIf
 If Not hmem ;If we didn't get a dib, return a dummy bitmap
  dib = FreeImage_Allocate(1, 1, 24, $ff0000, $00ff00, $0000ff)
  Return dib ;Fail
 EndIf

 phdr = FiApiGlobalLock(hmem) ;Lock memory and get pointer to it
 bank = CreateBank(40) ;Init bank, we will resize it later
 FiApiMemoryToBank(bank, phdr, 40) ;Move info header to bank
 shdr = PeekInt(bank, 0) ;biSize

 ;Calc palette, Clipboard dibs use the BITMAPINFO struct
 spal = PeekInt(bank, 32) ;biClrUsed
 If Not spal
  If PeekShort(bank, 14) <> 24 ;No color table for 24-bit
   spal=1 Shl PeekShort(bank, 14) ;biBitCount, colors=2/16/256
  EndIf
 EndIf
 spal = spal * 4 ;sizeof(RGBQUAD)
 bw = PeekInt(bank, 4) ;biWidth
 bh = PeekInt(bank, 8) ;biHeight
 bpp = PeekShort(bank, 14) ;biBitCount

 ;Calc bits, DWORD-aligned scanline (Width * BitCount) * Height
 sbits = ((bw * bpp + 31) / 32 * 4) * bh
 sdib = shdr + spal + sbits ;Total size
 ResizeBank bank, sdib ;Resize bank to store dib
 FiApiMemoryToBank(bank, phdr, sdib) ;Move dib to bank
 FiApiGlobalUnlock(hmem) ;Unlock the dib

 ;Alloc FreeImage bitmap, this has its own info header
 dib = FreeImage_Allocate(bw, bh, bpp, $ff0000, $00ff00, $0000ff)
 ppal = FreeImage_GetPalette(dib) ;Pointer to palette
 pbits = FreeImage_GetBits(dib) ;Pointer to bits

 ;Move palette and bits (not header) separately for proper alignment
 CopyBank bank, shdr, bank, 0, spal ;Move palette down
 FiApiBankToMemory(ppal, bank, spal) ;Move palette to memory
 CopyBank bank, shdr + spal, bank, 0, sbits ;Move bits down
 FiApiBankToMemory(pbits, bank, sbits) ;Move bits to memory

 FreeBank bank
 Return dib ;Success

End Function

;Bank functions

Function FiBankFromFile(filename$, size = 0, pos = 0)
 ;Creates and reads a bank from filename$
 ;size -> file size, pos -> file position
 ;Returns a bank

 Local bank, file
 If size = 0 Then size = FileSize(filename$)
 bank = CreateBank(size)
 file = ReadFile(filename$)
 If file
  SeekFile(file, pos)
  ReadBytes(bank, file, 0, size)
  CloseFile(file)
 EndIf
 Return bank

End Function

Function FiBankToFile(bank, filename$, size = 0, pos = 0)
 ;Appends a bank to filename$
 ;size -> file size, pos -> file position
 ;Returns True if succeeds or False if fails

 Local file
 If bank = 0 Then Return 0 ;No bank
 If size = 0 Then size = FileSize(filename$)
 file = OpenFile(filename$) ;Existing file
 If file = 0 Then file = WriteFile(filename$) ;New file
 If file
  SeekFile(file, pos)
  WriteBytes(bank, file, 0, size)
  CloseFile(file)
  file = 1
 EndIf
 Return file

End Function

Function FiLoadFromBank(bank)
 ;Loads a FreeImage bitmap from a bank
 ;Returns a FreeImage bitmap or False if fails

 Local stream, fif, dib
 If bank = 0 Then Return 0 ;No bank
 stream = FreeImage_OpenMemory(bank, BankSize(bank)) ;Attach to memory
 fif = FreeImage_GetFileTypeFromMemory(stream, 0) ;Format from filetype
 If fif >= 0 ;Format is valid
  dib = FreeImage_LoadFromMemory(fif, stream, 0) ;Load from memory
 EndIf
 FreeImage_CloseMemory(stream) ;Close memory
 Return dib

End Function

;Zlib functions

Function FiZlibLoadImage(filename$, datafile$)
 ;Loads an image from a zlib compressed file stored in datafile$
 ;Returns an image
 ;Uses FiZlibUnpack, FiLoadFromBank and FiRead

 Local bank, dib, image
 bank = FiZlibUnpack(filename$, datafile$)
 dib = FiLoadFromBank(bank)
 image = FiRead(dib)
 FreeBank bank
 FreeImage_Unload(dib)
 Return image

End Function

Function FiZlibPack(filename$, datafile$)
 ;Compresses a file with zlib and appends it to datafile$
 ;Returns True if succeeds or False if fails
 ;Uses FiBankFromFile and FiBankToFile

 Local file, hdrsize, pos, dstsize, srcsize
 Local dataname$, count, srcbank, dstbank

 file = ReadFile(datafile$)
 If file ;Check if file exists
  hdrsize = ReadInt(file) ;"zlib" file type header
  While Not Eof(file)
   pos = FilePos(file)
   dstsize = ReadInt(file)
   srcsize = ReadInt(file)
   dataname$ = ""
   For count = 1 To Len(filename$)
    dataname$ = dataname$ + Chr(ReadByte(file))
   Next
   If filename$ = dataname$ Then count = -1 : Exit ;Found file
   SeekFile(file, pos + dstsize) ;Next file block
  Wend
  CloseFile(file)
  If count < 0 Then Return 1 ;File exists, don't save
 EndIf

 srcsize = FileSize(filename$) ;Load uncompressed file
 hdrsize = Len(filename$) + 9
 dstsize = srcsize + Int(srcsize * 0.1) + 12
 srcbank = FiBankFromFile(filename$, dstsize + hdrsize)

 dstbank = CreateBank(dstsize + hdrsize) ;Compress file
 dstsize = FreeImage_ZLibCompress(dstbank, dstsize, srcbank, srcsize)
 CopyBank dstbank, 0, srcbank, hdrsize, dstsize ;Room for header
 PokeInt srcbank, 0, dstsize + hdrsize ;Compressed + header size
 PokeInt srcbank, 4, srcsize ;Uncompressed size
 For count = 1 To Len(filename$) ;Filename
  PokeByte srcbank, count + 7, Asc(Mid(filename$, count, 1))
 Next
 PokeByte srcbank, hdrsize - 1, 0 ;Null terminator

 If FileType(datafile$) = 0 ;File doesn't exist
  file = WriteFile(datafile$)
  WriteInt file, $62696c7a ;"zlib" file type header
  CloseFile(file)
 EndIf

 srcsize = FileSize(datafile$) ;Save compressed file
 FiBankToFile(srcbank, datafile$, dstsize + hdrsize, srcsize)
 FreeBank dstbank
 FreeBank srcbank
 Return file

End Function

Function FiZlibUnpack(filename$, datafile$)
 ;Uncompresses a zlib compressed file stored in datafile$
 ;Returns a bank or False if fails
 ;Uses FiBankFromFile

 Local file, hdrsize, pos, dstsize, srcsize
 Local dataname$, count, srcbank, dstbank

 file = ReadFile(datafile$)
 If file ;Check if file exists
  hdrsize = ReadInt(file) ;"zlib" file type header
  While Not Eof(file)
   pos = FilePos(file)
   dstsize = ReadInt(file)
   srcsize = ReadInt(file)
   dataname$ = ""
   For count = 1 To Len(filename$)
    dataname$ = dataname$ + Chr(ReadByte(file))
   Next
   If filename$ = dataname$ Then count = -1 : Exit ;Found file
   SeekFile(file, pos + dstsize) ;Next file block
  Wend
  CloseFile(file)
  If count >= 0 Then Return 0 ;File doesn't exist, don't load
 EndIf

 hdrsize = Len(filename$) + 9 ;Load compressed file
 dstsize = dstsize - hdrsize
 srcbank = FiBankFromFile(datafile$, srcsize, pos + hdrsize)

 dstbank = CreateBank(srcsize) ;Uncompress file
 dstsize = FreeImage_ZLibUncompress(dstbank, srcsize, srcbank, dstsize)
 FreeBank srcbank
 Return dstbank

End Function

Function FiGZipLoadImage(filename$, datafile$)
 ;Loads an image from a gzip compressed file stored in datafile$
 ;Returns an image
 ;Uses FiGUnzip, FiLoadFromBank and FiRead

 Local bank, dib, image
 bank = FiGUnzip(filename$, datafile$)
 dib = FiLoadFromBank(bank)
 image = FiRead(dib)
 FreeBank bank
 FreeImage_Unload(dib)
 Return image

End Function

Function FiGZip(filename$, datafile$)
 ;Compresses a file with gzip and appends it to datafile$
 ;Returns True if succeeds or False if fails
 ;Uses FiBankFromFile and FiBankToFile

 Local file, hdrsize, pos, dstsize, srcsize
 Local dataname$, count, srcbank, dstbank

 file = ReadFile(datafile$)
 If file ;Check if file exists
  hdrsize = ReadInt(file) ;"gzip" file type header
  While Not Eof(file)
   pos = FilePos(file)
   dstsize = ReadInt(file)
   srcsize = ReadInt(file)
   dataname$ = ""
   For count = 1 To Len(filename$)
    dataname$ = dataname$ + Chr(ReadByte(file))
   Next
   If filename$ = dataname$ Then count = -1 : Exit ;Found file
   SeekFile(file, pos + dstsize) ;Next file block
  Wend
  CloseFile(file)
  If count < 0 Then Return 1 ;File exists, don't save
 EndIf

 srcsize = FileSize(filename$) ;Load uncompressed file
 hdrsize = Len(filename$) + 9
 dstsize = srcsize + Int(srcsize * 0.1) + 24
 srcbank = FiBankFromFile(filename$, dstsize + hdrsize)

 dstbank = CreateBank(dstsize + hdrsize) ;Compress file
 dstsize = FreeImage_ZLibGZip(dstbank, dstsize, srcbank, srcsize)
 CopyBank dstbank, 0, srcbank, hdrsize, dstsize ;Room for header
 PokeInt srcbank, 0, dstsize + hdrsize ;Compressed + header size
 PokeInt srcbank, 4, srcsize ;Uncompressed size
 For count = 1 To Len(filename$) ;Filename
  PokeByte srcbank, count + 7, Asc(Mid(filename$, count, 1))
 Next
 PokeByte srcbank, hdrsize - 1, 0 ;Null terminator

 If FileType(datafile$) = 0 ;File doesn't exist
  file = WriteFile(datafile$)
  WriteInt file, $70697a67 ;"gzip" file type header
  CloseFile(file)
 EndIf

 srcsize = FileSize(datafile$) ;Save compressed file
 FiBankToFile(srcbank, datafile$, dstsize + hdrsize, srcsize)
 FreeBank dstbank
 FreeBank srcbank
 Return file

End Function

Function FiGUnzip(filename$, datafile$)
 ;Uncompresses a gzip compressed file stored in datafile$
 ;Returns a bank or False if fails
 ;Uses FiBankFromFile

 Local file, hdrsize, pos, dstsize, srcsize
 Local dataname$, count, srcbank, dstbank

 file = ReadFile(datafile$)
 If file ;Check if file exists
  hdrsize = ReadInt(file) ;"gzip" file type header
  While Not Eof(file)
   pos = FilePos(file)

   dstsize = ReadInt(file)
   srcsize = ReadInt(file)
   dataname$ = ""
   For count = 1 To Len(filename$)
    dataname$ = dataname$ + Chr(ReadByte(file))
   Next
   If filename$ = dataname$ Then count = -1 : Exit ;Found file
   SeekFile(file, pos + dstsize) ;Next file block
  Wend
  CloseFile(file)
  If count >= 0 Then Return 0 ;File doesn't exist, don't load
 EndIf

 hdrsize = Len(filename$) + 9 ;Load compressed file
 dstsize = dstsize - hdrsize
 srcbank = FiBankFromFile(datafile$, srcsize, pos + hdrsize)

 dstbank = CreateBank(srcsize) ;Uncompress file
 dstsize = FreeImage_ZLibGUnzip(dstbank, srcsize, srcbank, dstsize)
 FreeBank srcbank
 Return dstbank

End Function

;Memory stream functions

Function FiSaveToMemory(filename$)
 ;Loads a FreeImage bitmap and saves it to a memory stream
 ;Returns a FreeImage memory stream or False if fails

 Local fif, dib, stream
 fif = FreeImage_GetFileType(filename$, 0) ;Format from filetype
 If fif >= 0 ;Format is valid
  dib = FreeImage_Load(fif, filename$, 0)
  stream = FreeImage_OpenMemory(dib, 0) ;Attach to memory
  FreeImage_SaveToMemory(fif, dib, stream, 0) ;Save to memory
  FreeImage_Unload(dib)
 EndIf
 Return stream

End Function

Function FiLoadFromMemory(stream)
 ;Loads a FreeImage bitmap from a memory stream
 ;Returns a FreeImage bitmap or False if fails

 Local fif, dib
 FreeImage_SeekMemory(stream, 0, 0) ;Seek to memory start
 fif = FreeImage_GetFileTypeFromMemory(stream, 0) ;Format from memory
 If fif >= 0 ;Format is valid
  dib = FreeImage_LoadFromMemory(fif, stream, 0)
 EndIf
 Return dib

End Function

Function FiMemoryToFile(stream, filename$)
 ;Saves a memory stream as filename$
 ;Assumes the file extension is known
 ;Returns True if succeeds or False if fails
 ;Uses Kernel32.dll

 Local buf, size, bank, file
 buf = CreateBank(4) ;Memory buffer
 size = CreateBank(4) ;Size of buffer
 FreeImage_AcquireMemory(stream, buf, size) ;Get buffer from stream
 bank = CreateBank(PeekInt(size, 0)) ;Bank for bitmap
 FiApiMemoryToBank(bank, PeekInt(buf, 0), PeekInt(size, 0)) ;Move to bank
 file = WriteFile(filename$)
 If file ;Check if file opened
  WriteBytes bank, file, 0, PeekInt(size, 0)
  CloseFile(file)
 EndIf
 FreeBank buf ;Free banks
 FreeBank size
 FreeBank bank
 If file Then file = 1
 Return file

End Function

Function FiMemorySize(stream)
 ;Returns the size of a FreeImage bitmap in a memory stream

 Local size
 FreeImage_SeekMemory(stream, 0, 2) ;Seek to memory end
 size = FreeImage_TellMemory(stream) ;Memory position is file size
 Return size

End Function

Function FiCloseMemory(stream)
 ;Frees a FreeImage bitmap in a memory stream, a wrapper function
 ;Returns nothing

 FreeImage_CloseMemory(stream)

End Function

;FiRotateClassicEx functions

Function FiRotateAny(hsrc, angle#, bgcolor)
 ;Rotates an image by a degree. Angle is unlimited
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon

 Local hmid, hdst

 hmid = hsrc ;Init middle
 While angle# < 0 : angle# = angle# + 360 : Wend ;Wrap angle to 0..360
 While angle# >= 360 : angle# = angle# - 360 : Wend

 If angle# > 45 And angle# <= 135 ;Angle in range 45..135
  hmid = FiRotate90(hsrc)
  angle# = angle# - 90
 ElseIf angle# > 135 And angle# <= 225 ;Angle in range 135..225
  hmid = FiRotate180(hsrc)
  angle# = angle# - 180
 ElseIf angle# > 225 And angle# <= 315 ;Angle in range 225..315
  hmid = FiRotate270(hsrc)
  angle# = angle# - 270
 EndIf

 If angle# = 0 ;Angle is 0
  If hmid = hsrc ;Nothing to do
   Return FreeImage_Clone(hsrc) ;Clone handle
  Else ;No more rotation needed
   Return hmid ;Rotated handle, multiple of 90
  EndIf
 Else ;Last rotation, angle in range -45..45
  hdst = FiRotate45(hmid, angle#, bgcolor)
  If hmid <> hsrc ;Middle conversion required
   FreeImage_Unload(hmid) ;Free from memory
  EndIf
  Return hdst ;Rotated handle, sheared
 EndIf

End Function

Function FiRotate45(hsrc, angle#, bgcolor)
 ;Rotates an image by a degree in range -45..45 (counter clockwise)
 ;Using the 3-shear technique
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon

 Local bpp, sinv#, tanv#, srcw, srch, i, shear#, offset, weight
 Local w1, h1, hdst1, w2, h2, hdst2, w3, h3, hdst3

 bpp = FreeImage_GetBPP(hsrc) ;Init values
 sinv# = Sin(angle#)
 tanv# = Tan(angle# / 2)
 srcw = FreeImage_GetWidth(hsrc)
 srch = FreeImage_GetHeight(hsrc)

 h1 = srch ;Calc 1st shear destination image dimensions
 w1 = srcw + Int(Float(srch) * Abs(tanv#) + 0.5)
 hdst1 = FreeImage_Allocate(w1, h1, bpp, 0, 0, 0)
 For i = 0 To h1 - 1 ;Perform 1st shear (horizontal)
  If tanv# >= 0 ;Positive angle
   shear# = (Float(i) + 0.5) * tanv#
  Else ;Negative angle
   shear# = (Float(Int(i) - h1) + 0.5) * tanv#
  EndIf
  offset = Int(Floor(shear#))
  weight = 255 * (shear# - Float(offset)) ;Was weight+1
  While weight < 0 : weight = weight + 256 : Wend ;Wrap byte to 0..255
  While weight > 255 : weight = weight - 256 : Wend
  FiHorizontalSkew(hsrc, hdst1, i, offset, weight, bgcolor)
 Next

 w2 = w1 ;Calc 2nd shear destination image dimensions
 h2 = Float(srcw) * Abs(sinv#) + Float(srch) * Cos(angle#) + 0.5
 hdst2 = FreeImage_Allocate(w2, h2, bpp, 0, 0, 0)
 If sinv# >= 0 ;Positive angle
  shear# = Float(srcw - 1) * sinv#
 Else ;Negative angle
  shear# = -sinv# * Float(srcw - w2)
 EndIf
 For i = 0 To w2 - 1 ;Perform 2nd shear (vertical)
  shear# = shear# - sinv#
  offset = Int(Floor(shear#))
  weight = 255 * (shear# - Float(offset)) ;Was weight+1
  While weight < 0 : weight = weight + 256 : Wend ;Wrap byte to 0..255
  While weight > 255 : weight = weight - 256 : Wend
  offset = offset + 1 ;Was offset
  FiVerticalSkew(hdst1, hdst2, i, offset, weight, bgcolor)
 Next
 FreeImage_Unload(hdst1) ;Free 1st shear

 h3 = h2 ;Calc 3rd shear destination image dimensions
 w3 = Float(srch) * Abs(sinv#) + Float(srcw) * Cos(angle#) + 0.5
 hdst3 = FreeImage_Allocate(w3, h3, bpp, 0, 0, 0)
 If sinv# >= 0 ;Positive angle
  shear# = Float(srcw - 1) * sinv#* - tanv#
 Else ;Negative angle
  shear# = tanv#*(Float(srcw - 1) * -sinv# + Float(1 - h3))
 EndIf
 For i = 0 To h3 - 1 ;Perform 3rd shear (horizontal)
  shear# = shear# + tanv#
  offset = Int(Floor(shear#))
  weight = 255 * (shear# - Float(offset)) ;Was weight+1
  While weight < 0 : weight = weight + 256 : Wend ;Wrap byte to 0..255
  While weight > 255 : weight = weight - 256 : Wend
  FiHorizontalSkew(hdst2, hdst3, i, offset, weight, bgcolor)
 Next
 FreeImage_Unload(hdst2) ;Free 2nd shear

 Return hdst3 ;3rd shear handle

End Function

Function FiHorizontalSkew(hsrc, hdst, row, offset, weight, bgcolor)
 ;Skews a row horizontally (with filtered weights)
 ;Limited to 45 degree skewing only. Filters two adjacent pixels
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon

 Local pxlsrc, pxlleft, pxloldleft, srcw, dstw, bytespp, i, j, ix, byte

 pxlsrc = CreateBank(12) ;4 byte arrays, for 32bit max
 pxlleft = 4 ;2nd array offset
 pxloldleft = 8 ;3rd array offset
 srcw = FreeImage_GetWidth(hsrc) + 2 ;Was srcw
 dstw = FreeImage_GetWidth(hdst)
 bytespp = FreeImage_GetLine(hsrc) / FreeImage_GetWidth(hsrc)

 For i = 0 To srcw - 1 ;Loop through row pixels
  PokeInt pxlsrc, 0, bgcolor ;Get background color
  If i > 0 And i < srcw - 1 ;Source in bounds
   FreeImage_GetPixelColor(hsrc, i - 1, row, pxlsrc) ;Was i
  EndIf
  For j = 0 To bytespp - 1 ;Calc weights
   PokeByte pxlsrc, j + pxlleft, PeekByte(pxlsrc, j) * weight / 256
  Next
  ix = i + offset - 1 ;Was offset
  If ix >= 0 And ix < dstw ;Check boundaries
   For j = 0 To bytespp - 1 ;Update left over on source
    byte=PeekByte(pxlsrc, j + pxlleft) - PeekByte(pxlsrc, j + pxloldleft)
    PokeByte pxlsrc, j, PeekByte(pxlsrc, j) - byte
   Next
   FreeImage_SetPixelColor(hdst, ix, row, pxlsrc)
  EndIf
  For j = 0 To bytespp - 1 ;Save leftover for next pixel in scan
   PokeByte pxlsrc, j + pxloldleft, PeekByte(pxlsrc, j + pxlleft)
  Next
 Next

 PokeInt pxlsrc, 0, bgcolor ;Get background color

 ix = srcw + offset - 1 ;Go to rightmost point of skew, nb: offset
 While ix < dstw ;Fill gap right of skew with background
  FreeImage_SetPixelColor(hdst, ix, row, pxlsrc)
  ix = ix + 1 ;Was ix
 Wend

 If offset > 0
  For j = 0 To offset - 1 ;Fill gap left of skew with background
   FreeImage_SetPixelColor(hdst, j, row, pxlsrc)
  Next
 EndIf

 FreeBank pxlsrc ;Free from memory

End Function

Function FiVerticalSkew(hsrc, hdst, col, offset, weight, bgcolor)
 ;Skews a column vertically (with filtered weights)
 ;Limited to 45 degree skewing only. Filters two adjacent pixels
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon

 Local pxlsrc, pxlleft, pxloldleft, srch, dsth, bytespp, i, j, iy, byte

 pxlsrc = CreateBank(12) ;4 byte arrays, for 32bit max
 pxlleft = 4 ;2nd array offset
 pxloldleft = 8 ;3rd array offset
 srch = FreeImage_GetHeight(hsrc) + 2 ;Was srch
 dsth = FreeImage_GetHeight(hdst)
 bytespp = FreeImage_GetLine(hsrc) / FreeImage_GetWidth(hsrc)

 For i = 0 To srch - 1 ;Loop through column pixels
  PokeInt pxlsrc, 0, bgcolor ;Get background color
  If i > 0 And i < srch - 1 ;Source in bounds
   FreeImage_GetPixelColor(hsrc, col, i - 1, pxlsrc) ;Was i
  EndIf
  For j = 0 To bytespp - 1 ;Calc weights
   PokeByte pxlsrc, j + pxlleft, PeekByte(pxlsrc, j) * weight / 256
  Next
  iy = i + offset - 1 ;Was offset
  If iy >= 0 And iy < dsth ;Check boundaries
   For j = 0 To bytespp - 1 ;Update left over on source
    byte = PeekByte(pxlsrc, j + pxlleft) - PeekByte(pxlsrc, j + pxloldleft)
    PokeByte pxlsrc, j, PeekByte(pxlsrc, j) - byte
   Next
   FreeImage_SetPixelColor(hdst, col, iy, pxlsrc)
  EndIf
  For j = 0 To bytespp - 1 ;Save leftover for next pixel in scan
   PokeByte pxlsrc, j + pxloldleft, PeekByte(pxlsrc, j + pxlleft)
  Next
 Next

 PokeInt pxlsrc, 0, bgcolor ;Get background color

 iy = srch + offset - 1 ;Go to bottom point of skew, nb: offset
 While iy < dsth ;Fill gap below skew with background
  FreeImage_SetPixelColor(hdst, col, iy, pxlsrc)
  iy = iy + 1 ;Was iy
 Wend

 If offset > 0
  For i = 0 To offset - 1 ;Fill gap above skew with background
   FreeImage_SetPixelColor(hdst, col, i, pxlsrc)
  Next
 EndIf

 FreeBank pxlsrc ;Free from memory

End Function

Function FiRotate90(hsrc)
 ;Rotates an image by 90 degrees (counter clockwise)
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon
 ;Code adapted from CxImage: www.xdp.it/cximage.htm

 Local pcolor, bpp, width, height, hdst, xs, ys, minw, minh, x, y, y2

 pcolor = CreateBank(4) ;Bank structure, for 32 bit max
 bpp = FreeImage_GetBPP(hsrc)
 width = FreeImage_GetHeight(hsrc)
 height = FreeImage_GetWidth(hsrc)
 hdst = FreeImage_Allocate(width, height, bpp, 0, 0, 0)

 For ys = 0 To height - 1 Step 64 ;Loop for x-segment and y-segment
  For xs = 0 To width - 1 Step 64 ;64=rblock, size of image blocks
   minh = height : If ys + 64 < height Then minh = ys + 64
   For y = ys To minh - 1 ;Do rotation
    y2 = height - y - 1
    minw = width : If xs + 64 < width Then minw = xs + 64
    For x = xs To minw - 1
     FreeImage_GetPixelColor(hsrc, y2, x, pcolor)
     FreeImage_SetPixelColor(hdst, x, y, pcolor)
    Next
   Next
  Next
 Next

 FreeBank pcolor ;Free from memory

 Return hdst ;Rotated handle

End Function

Function FiRotate180(hsrc)
 ;Rotates an image by 180 degrees (counter clockwise)
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon

 Local pcolor, bpp, width, height, hdst, x, y

 pcolor = CreateBank(4) ;Bank structure, for 32 bit max
 bpp = FreeImage_GetBPP(hsrc)
 width = FreeImage_GetWidth(hsrc)
 height = FreeImage_GetHeight(hsrc)
 hdst = FreeImage_Allocate(width, height, bpp, 0, 0, 0)

 For y = 0 To height - 1
  For x = 0 To width - 1
   FreeImage_GetPixelColor(hsrc, x, y, pcolor)
   FreeImage_SetPixelColor(hdst, width - x - 1, height - y - 1, pcolor)
  Next
 Next

 FreeBank pcolor ;Free from memory

 Return hdst ;Rotated handle

End Function

Function FiRotate270(hsrc)
 ;Rotates an image by 270 degrees (counter clockwise)
 ;Used by FiRotateClassicEx
 ;From FreeImage source by Hervé Drolon
 ;Code adapted from CxImage: www.xdp.it/cximage.htm

 Local pcolor, bpp, width, height, hdst, xs, ys, minw, minh, x, y, x2

 pcolor = CreateBank(4) ;Bank structure, for 32 bit max
 bpp = FreeImage_GetBPP(hsrc)
 width = FreeImage_GetHeight(hsrc)
 height = FreeImage_GetWidth(hsrc)
 hdst = FreeImage_Allocate(width, height, bpp, 0, 0, 0)

 For ys = 0 To height - 1 Step 64 ;Loop for x-segment and y-segment
  For xs = 0 To width - 1 Step 64 ;rblock=64, size of image blocks
   minw = width : If xs + 64 < width Then minw = xs + 64
   For x = xs To minw - 1 ;Do rotation
    x2 = width - x - 1
    minh = height : If ys + 64 < height Then minh = ys + 64
    For y = ys To minh - 1
     FreeImage_GetPixelColor(hsrc, y, x2, pcolor)
     FreeImage_SetPixelColor(hdst, x, y, pcolor)
    Next
   Next
  Next
 Next

 FreeBank pcolor ;Free from memory

 Return hdst ;Rotated handle

End Function

;FloatToDouble functions

Function FiFloatToDouble(value#, dpart = 0)
 ;Converts a float into a double as 2 integers
 ;dpart -> Double flag indicating which part to return, 0=dlo, 1=dhi
 ;Returns a low or high double integer - decimal equivalent of the float
 ;Site: techsupt.winbatch.com/TS/T000001034F21.html

 Local integer, sign, exponent, fraction, dexp, dlo, dhi
 integer = FiFloatToInt(value#)
 sign = integer And $80000000 ;Sign bit
 exponent = integer And $7F800000 ;8-bit exponent
 fraction = integer And $007FFFFF ;23-bit mantissa
 dexp = ((exponent Shr 23) - 127 + 1023) Shl 20 ;Double exponent
 dlo = (fraction And 7) Shl 29
 dhi = sign Or dexp Or (fraction Shr 3)
 If dpart = 0 Then Return dlo
 Return dhi

End Function

Function FiDoubleToFloat#(dlo, dhi)
 ;Converts a double as 2 integers into a float
 ;dlo -> Low double integer, dhi -> High double integer
 ;Returns a float - decimal equivalent of the double as 2 integers
 ;Site: techsupt.winbatch.com/TS/T000001034F21.html


 Local dsgn, sign, dexp, exponent, fraction
 dsgn = Abs(dhi Shr 31) ;Double sign
 sign = dsgn Shl 31 ;Sign bit
 dexp = Abs((dhi Shr 20) - (dsgn Shl 11)) ;Double exponent
 exponent = (dexp + 127 - 1023) Shl 23 ;8-bit exponent
 fraction = ((dhi And $000FFFFF) Shl 3) + (dlo Shr 29) ;23-bit mantissa
 Return FiIntToFloat(sign Or exponent Or fraction)

End Function

Function FiFloatToInt(value#)
 ;Converts a float into a float as an integer
 ;Returns an integer that is the binary equivalent of the float
 ;Site: wiki.tcl.tk/756

 Local sign, exponent, fraction#
 Local f1f#, f2f#, f3f#, se1, e2f1, f1, f2, f3
 If value# > 0 Then sign = 0 Else sign = 1
 value# = Abs(value#)
 exponent = Int(Floor(Log(value#) / 0.69314718055994529)) + 127
 fraction# = (value# / (2 ^ (exponent - 127))) - 1
 If exponent < 0 Then exponent = 0 : fraction# = 0.0 ;Round off to zero
 If exponent > 255 Then exponent = 255 ;Outside legal range for a float
 fraction# = fraction# * 128.0
 f1f# = Floor(fraction#)
 fraction# = (fraction# - f1f#) * 256.0
 f2f# = Floor(fraction#)
 fraction# = (fraction# - f2f#) * 256.0
 f3f# = Floor(fraction#)
 f1 = Int(f1f#) : f2 = Int(f2f#) : f3 = Int(f3f#)
 se1 = (sign Shl 7) Or (exponent Shr 1) ;Sign and Exponent1
 e2f1 = ((exponent And 1) Shl 7) Or f1 ;Exponent2 and Fraction1
 Return (se1 Shl 24) Or (e2f1 Shl 16) Or (f2 Shl 8) Or f3

End Function

Function FiIntToFloat#(value)
 ;Converts a float as an integer into a float
 ;Returns a float that is the binary equivalent of the integer
 ;Site: www.cs.princeton.edu/introcs/91float/

 Local sign, exponent, fraction
 sign = (value And $80000000) Shr 31
 exponent = (value And $7F800000) Shr 23
 fraction = value And $007FFFFF
 Return (-1 ^ sign) * (2 ^ (exponent - 127)) * (1 + (fraction / (2 ^ 23)))

End Function

;End of FreeImage Module


Save these decls as "freeimage.decls" in your userlibs folder.
.lib " "
;FreeImage Module Decls

;Load and save image functions
FiLoadImage%(filename$)
FiSaveImage%(image, filename$)
FiLoad%(filename$)
FiRead%(dib)
FiSave%(dib, filename$)
FiWrite%(image)
FiUnload(dib)

;Load and save anim image functions
FiLoadAnimImage%(filename$, index, frames)
FiSaveAnimImage%(image, filename$, frames, index)
FiAnimFrames%(filename$, index, frames)
FiOpenAnim%(filename$, opentype, flags)
FiCloseAnim(dib, flags)

;Image manipulation functions
FiRescale%(bitmap, scale, filter)
FiRotateClassic%(dib, angle#)
FiRotateClassicEx%(dib, angle#, bgcolor)
FiAdjustGamma%(dib, gamma#)
FiAdjustBrightness%(dib, brightness#)
FiAdjustContrast%(dib, contrast#)
FiAdjustIntensity%(dib, intensity#)

;Information functions
FiGetWidth%(dib)
FiGetHeight%(dib)
FiGetBPP%(dib)

;Clipboard functions
FiCopyToClipboard%(dib)
FiPasteFromClipboard%()

;Bank functions
FiBankFromFile%(filename$)
FiBankToFile%(bank, filename$, size)
FiLoadFromBank%(bank)

;Zlib functions
FiZlibLoadImage%(filename$, datafile$)
FiZlibPack%(filename$, datafile$)
FiZlibUnpack%(filename$, datafile$)
FiGZipLoadImage%(filename$, datafile$)
FiGZip%(filename$, datafile$)
FiGUnzip%(filename$, datafile$)

;Memory stream functions
FiSaveToMemory%(filename$)
FiLoadFromMemory%(stream)
FiMemoryToFile%(stream, filename$)
FiMemorySize%(stream)
FiCloseMemory(stream)

;FiRotateClassicEx functions
FiRotateAny%(hsrc, angle#, bgcolor)
FiRotate45%(hsrc, angle#, bgcolor)
FiHorizontalSkew%(hsrc, hdst, row, offset, weight, bgcolor)
FiVerticalSkew%(hsrc, hdst, col, offset, weight, bgcolor)
FiRotate90%(hsrc)
FiRotate180%(hsrc)
FiRotate270%(hsrc)

;FloatToDouble functions
FiFloatToDouble%(value#, dpart)
FiDoubleToFloat#(dho, dhi)
FiFloatToInt%(value#)
FiIntToFloat#(value)

.lib "Kernel32.dll"
;Memory Management Functions

FiApiGlobalAlloc%(uFlags,dwBytes):"GlobalAlloc"
FiApiGlobalLock%(hmem):"GlobalLock"
FiApiGlobalUnlock%(hmem):"GlobalUnlock"
FiApiBankToMemory(dst, src*, len):"RtlMoveMemory"
FiApiMemoryToBank(dst*, src, len):"RtlMoveMemory"

.lib "User32.dll"
;Clipboard Functions

FiApiCloseClipboard%():"CloseClipboard"
FiApiEmptyClipboard%():"EmptyClipboard"
FiApiGetClipboardData%(uFormat):"GetClipboardData"
FiApiIsClipboardFormatAvailable%(format):"IsClipboardFormatAvailable"
FiApiOpenClipboard%(hwnd):"OpenClipboard"
FiApiSetClipboardData%(uFormat,hData):"SetClipboardData"

.lib "FreeImage.dll"
;FreeImage 3.10.0 Decls
;http://freeimage.sourceforge.net/

;Init / Error Routines
FreeImage_Initialise(load_local_plugins_only):"_FreeImage_Initialise@4"
FreeImage_DeInitialise():"_FreeImage_DeInitialise@0"

;Version Routines
FreeImage_GetVersion$():"_FreeImage_GetVersion@0"
FreeImage_GetCopyrightMessage$():"_FreeImage_GetCopyrightMessage@0"

;Message Output Functions
FreeImage_SetOutputMessageStdCall(omf):"_FreeImage_SetOutputMessageStdCall@4"
FreeImage_SetOutputMessage(omf):"_FreeImage_SetOutputMessage@4"
FreeImage_OutputMessageProc(fif,fmt$):"FreeImage_OutputMessageProc"

;Allocate / Clone / Unload Routines
FreeImage_Allocate%(width,height,bpp,red_mask,green_mask,blue_mask):"_FreeImage_Allocate@24"
FreeImage_AllocateT%(type,width,height,bpp,red_mask,green_mask,blue_mask):"_FreeImage_AllocateT@28"
FreeImage_Clone%(dib):"_FreeImage_Clone@4"
FreeImage_Unload(dib):"_FreeImage_Unload@4"

;Load / Save Routines
FreeImage_Load%(fif,filename$,flags):"_FreeImage_Load@12"
FreeImage_LoadU%(fif,filename$,flags):"_FreeImage_LoadU@12"
FreeImage_LoadFromHandle%(fif,io*,handle,flags):"_FreeImage_LoadFromHandle@16"
FreeImage_Save%(fif,dib,filename$,flags):"_FreeImage_Save@16"
FreeImage_SaveU%(fif,dib,filename$,flags):"_FreeImage_SaveU@16"
FreeImage_SaveToHandle%(fif,dib,io*,handle,flags):"_FreeImage_SaveToHandle@20"

;Memory I/O Stream Routines
FreeImage_OpenMemory%(data*,size_in_bytes):"_FreeImage_OpenMemory@8"
FreeImage_CloseMemory(stream):"_FreeImage_CloseMemory@4"
FreeImage_LoadFromMemory%(fif,stream,flags):"_FreeImage_LoadFromMemory@12"
FreeImage_SaveToMemory%(fif,dib,stream,flags):"_FreeImage_SaveToMemory@16"
FreeImage_TellMemory%(stream):"_FreeImage_TellMemory@4"
FreeImage_SeekMemory%(stream,offset,origin):"_FreeImage_SeekMemory@12"
FreeImage_AcquireMemory%(stream,data*,size_in_bytes*):"_FreeImage_AcquireMemory@12"
FreeImage_ReadMemory%(buffer,size,count,stream):"_FreeImage_ReadMemory@16"
FreeImage_WriteMemory%(buffer,size,count,stream):"_FreeImage_WriteMemory@16"
FreeImage_LoadMultiBitmapFromMemory%(fif,stream,flags):"_FreeImage_LoadMultiBitmapFromMemory@12"

;Plugin Interface
FreeImage_RegisterLocalPlugin%(proc_address,format$,description$,extension$,regexpr$):"_FreeImage_RegisterLocalPlugin@20"
FreeImage_RegisterExternalPlugin%(path$,format$,description$,extension$,regexpr$):"_FreeImage_RegisterExternalPlugin@20"
FreeImage_GetFIFCount%():"_FreeImage_GetFIFCount@0"
FreeImage_SetPluginEnabled%(fif,enable):"_FreeImage_SetPluginEnabled@8"
FreeImage_IsPluginEnabled%(fif):"_FreeImage_IsPluginEnabled@4"
FreeImage_GetFIFFromFormat%(format$):"_FreeImage_GetFIFFromFormat@4"
FreeImage_GetFIFFromMime%(mime$):"_FreeImage_GetFIFFromMime@4"
FreeImage_GetFormatFromFIF$(fif):"_FreeImage_GetFormatFromFIF@4"
FreeImage_GetFIFExtensionList$(fif):"_FreeImage_GetFIFExtensionList@4"
FreeImage_GetFIFDescription$(fif):"_FreeImage_GetFIFDescription@4"
FreeImage_GetFIFRegExpr$(fif):"_FreeImage_GetFIFRegExpr@4"
FreeImage_GetFIFMimeType$(fif):"_FreeImage_GetFIFMimeType@4"
FreeImage_GetFIFFromFilename%(filename$):"_FreeImage_GetFIFFromFilename@4"
FreeImage_GetFIFFromFilenameU%(filename$):"_FreeImage_GetFIFFromFilenameU@4"
FreeImage_FIFSupportsReading%(fif):"_FreeImage_FIFSupportsReading@4"
FreeImage_FIFSupportsWriting%(fif):"_FreeImage_FIFSupportsWriting@4"
FreeImage_FIFSupportsExportBPP%(fif,bpp):"_FreeImage_FIFSupportsExportBPP@8"
FreeImage_FIFSupportsExportType%(fif,type):"_FreeImage_FIFSupportsExportType@8"
FreeImage_FIFSupportsICCProfiles%(fif):"_FreeImage_FIFSupportsICCProfiles@4"

;Multipaging Interface
FreeImage_OpenMultiBitmap%(fif,filename$,create_new,read_only,keep_cache_in_memory,flags):"_FreeImage_OpenMultiBitmap@24"
FreeImage_CloseMultiBitmap%(bitmap,flags):"_FreeImage_CloseMultiBitmap@8"
FreeImage_GetPageCount%(bitmap):"_FreeImage_GetPageCount@4"
FreeImage_AppendPage(bitmap,data):"_FreeImage_AppendPage@8"
FreeImage_InsertPage(bitmap,page,data):"_FreeImage_InsertPage@12"
FreeImage_DeletePage(bitmap,page):"_FreeImage_DeletePage@8"
FreeImage_LockPage%(bitmap,page):"_FreeImage_LockPage@8"
FreeImage_UnlockPage(bitmap,page,changed):"_FreeImage_UnlockPage@12"
FreeImage_MovePage%(bitmap,target,source):"_FreeImage_MovePage@12"
FreeImage_GetLockedPageNumbers%(bitmap,pages,count*):"_FreeImage_GetLockedPageNumbers@12"

;Filetype Request Routines
FreeImage_GetFileType%(filename$,size):"_FreeImage_GetFileType@8"
FreeImage_GetFileTypeU%(filename$,size):"_FreeImage_GetFileTypeU@8"
FreeImage_GetFileTypeFromHandle%(io*,handle,size):"_FreeImage_GetFileTypeFromHandle@12"
FreeImage_GetFileTypeFromMemory%(stream,size):"_FreeImage_GetFileTypeFromMemory@8"

;Image Type Request Routine
FreeImage_GetImageType%(dib):"_FreeImage_GetImageType@4"

;FreeImage Helper Routines
FreeImage_IsLittleEndian%():"_FreeImage_IsLittleEndian@0"
FreeImage_LookupX11Color%(szColor$,nRed*,nGreen*,nBlue*):"_FreeImage_LookupX11Color@16"
FreeImage_LookupSVGColor%(szColor$,nRed*,nGreen*,nBlue*):"_FreeImage_LookupSVGColor@16"

;Pixel Access Routines
FreeImage_GetBits%(dib):"_FreeImage_GetBits@4"
FreeImage_GetScanLine%(dib,scanline):"_FreeImage_GetScanLine@8"
FreeImage_GetPixelIndex%(dib,x,y,value*):"_FreeImage_GetPixelIndex@16"
FreeImage_GetPixelColor%(dib,x,y,value*):"_FreeImage_GetPixelColor@16"
FreeImage_SetPixelIndex%(dib,x,y,value*):"_FreeImage_SetPixelIndex@16"
FreeImage_SetPixelColor%(dib,x,y,value*):"_FreeImage_SetPixelColor@16"

;DIB Info Routines
FreeImage_GetColorsUsed%(dib):"_FreeImage_GetColorsUsed@4"
FreeImage_GetBPP%(dib):"_FreeImage_GetBPP@4"
FreeImage_GetWidth%(dib):"_FreeImage_GetWidth@4"
FreeImage_GetHeight%(dib):"_FreeImage_GetHeight@4"
FreeImage_GetLine%(dib):"_FreeImage_GetLine@4"
FreeImage_GetPitch%(dib):"_FreeImage_GetPitch@4"
FreeImage_GetDIBSize%(dib):"_FreeImage_GetDIBSize@4"
FreeImage_GetPalette%(dib):"_FreeImage_GetPalette@4"
FreeImage_GetDotsPerMeterX%(dib):"_FreeImage_GetDotsPerMeterX@4"
FreeImage_GetDotsPerMeterY%(dib):"_FreeImage_GetDotsPerMeterY@4"
FreeImage_SetDotsPerMeterX(dib,res):"_FreeImage_SetDotsPerMeterX@8"
FreeImage_SetDotsPerMeterY(dib,res):"_FreeImage_SetDotsPerMeterY@8"
FreeImage_GetInfoHeader%(dib):"_FreeImage_GetInfoHeader@4"
FreeImage_GetInfo%(dib):"_FreeImage_GetInfo@4"
FreeImage_GetColorType%(dib):"_FreeImage_GetColorType@4"
FreeImage_GetRedMask%(dib):"_FreeImage_GetRedMask@4"
FreeImage_GetGreenMask%(dib):"_FreeImage_GetGreenMask@4"
FreeImage_GetBlueMask%(dib):"_FreeImage_GetBlueMask@4"
FreeImage_GetTransparencyCount%(dib):"_FreeImage_GetTransparencyCount@4"
FreeImage_GetTransparencyTable%(dib):"_FreeImage_GetTransparencyTable@4"
FreeImage_SetTransparent(dib,enabled):"_FreeImage_SetTransparent@8"
FreeImage_SetTransparencyTable(dib,table*,count):"_FreeImage_SetTransparencyTable@12"
FreeImage_IsTransparent%(dib):"_FreeImage_IsTransparent@4"
FreeImage_SetTransparentIndex(dib,index):"_FreeImage_SetTransparentIndex@8"
FreeImage_GetTransparentIndex%(dib):"_FreeImage_GetTransparentIndex@4"
FreeImage_HasBackgroundColor%(dib):"_FreeImage_HasBackgroundColor@4"
FreeImage_GetBackgroundColor%(dib,bkcolor*):"_FreeImage_GetBackgroundColor@8"
FreeImage_SetBackgroundColor%(dib,bkcolor*):"_FreeImage_SetBackgroundColor@8"

;ICC Profile Routines
FreeImage_GetICCProfile%(dib):"_FreeImage_GetICCProfile@4"
FreeImage_CreateICCProfile%(dib,data,size):"_FreeImage_CreateICCProfile@12"
FreeImage_DestroyICCProfile%(dib):"_FreeImage_DestroyICCProfile@4"

;Line Conversion Routines
FreeImage_ConvertLine1To4(target*,source*,width_in_pixels):"_FreeImage_ConvertLine1To4@12"
FreeImage_ConvertLine8To4(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine8To4@16"
FreeImage_ConvertLine16To4_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To4_555@12"
FreeImage_ConvertLine16To4_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To4_565@12"
FreeImage_ConvertLine24To4(target*,source*,width_in_pixels):"_FreeImage_ConvertLine24To4@12"
FreeImage_ConvertLine32To4(target*,source*,width_in_pixels):"_FreeImage_ConvertLine32To4@12"
FreeImage_ConvertLine1To8(target*,source*,width_in_pixels):"_FreeImage_ConvertLine1To8@12"
FreeImage_ConvertLine4To8(target*,source*,width_in_pixels):"_FreeImage_ConvertLine4To8@12"
FreeImage_ConvertLine16To8_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To8_555@12"
FreeImage_ConvertLine16To8_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To8_565@12"
FreeImage_ConvertLine24To8(target*,source*,width_in_pixels):"_FreeImage_ConvertLine24To8@12"
FreeImage_ConvertLine32To8(target*,source*,width_in_pixels):"_FreeImage_ConvertLine32To8@12"
FreeImage_ConvertLine1To16_555(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine1To16_555@16"
FreeImage_ConvertLine4To16_555(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine4To16_555@16"
FreeImage_ConvertLine8To16_555(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine8To16_555@16"
FreeImage_ConvertLine16_565_To16_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16_565_To16_555@12"
FreeImage_ConvertLine24To16_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine24To16_555@12"
FreeImage_ConvertLine32To16_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine32To16_555@12"
FreeImage_ConvertLine1To16_565(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine1To16_565@16"
FreeImage_ConvertLine4To16_565(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine4To16_565@16"
FreeImage_ConvertLine8To16_565(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine8To16_565@16"
FreeImage_ConvertLine16_555_To16_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16_555_To16_565@12"
FreeImage_ConvertLine24To16_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine24To16_565@12"
FreeImage_ConvertLine32To16_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine32To16_565@12"
FreeImage_ConvertLine1To24(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine1To24@16"
FreeImage_ConvertLine4To24(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine4To24@16"
FreeImage_ConvertLine8To24(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine8To24@16"
FreeImage_ConvertLine16To24_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To24_555@12"
FreeImage_ConvertLine16To24_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To24_565@12"
FreeImage_ConvertLine32To24(target*,source*,width_in_pixels):"_FreeImage_ConvertLine32To24@12"
FreeImage_ConvertLine1To32(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine1To32@16"
FreeImage_ConvertLine4To32(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine4To32@16"
FreeImage_ConvertLine8To32(target*,source*,width_in_pixels,palette*):"_FreeImage_ConvertLine8To32@16"
FreeImage_ConvertLine16To32_555(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To32_555@12"
FreeImage_ConvertLine16To32_565(target*,source*,width_in_pixels):"_FreeImage_ConvertLine16To32_565@12"
FreeImage_ConvertLine24To32(target*,source*,width_in_pixels):"_FreeImage_ConvertLine24To32@12"

;Smart Conversion Routines
FreeImage_ConvertTo4Bits%(dib):"_FreeImage_ConvertTo4Bits@4"
FreeImage_ConvertTo8Bits%(dib):"_FreeImage_ConvertTo8Bits@4"
FreeImage_ConvertToGreyscale%(dib):"_FreeImage_ConvertToGreyscale@4"
FreeImage_ConvertTo16Bits555%(dib):"_FreeImage_ConvertTo16Bits555@4"
FreeImage_ConvertTo16Bits565%(dib):"_FreeImage_ConvertTo16Bits565@4"
FreeImage_ConvertTo24Bits%(dib):"_FreeImage_ConvertTo24Bits@4"
FreeImage_ConvertTo32Bits%(dib):"_FreeImage_ConvertTo32Bits@4"
FreeImage_ColorQuantize%(dib,quantize):"_FreeImage_ColorQuantize@8"
FreeImage_ColorQuantizeEx%(dib,quantize,PaletteSize,ReserveSize,ReservePalette*):"_FreeImage_ColorQuantizeEx@20"
FreeImage_Threshold%(dib,T):"_FreeImage_Threshold@8"
FreeImage_Dither%(dib,algorithm):"_FreeImage_Dither@8"
FreeImage_ConvertFromRawBits%(bits*,width,height,pitch,bpp,red_mask,green_mask,blue_mask,topdown):"_FreeImage_ConvertFromRawBits@36"
FreeImage_ConvertToRawBits(bits*,dib,pitch,bpp,red_mask,green_mask,blue_mask,topdown):"_FreeImage_ConvertToRawBits@32"
FreeImage_ConvertToRGBF%(dib):"_FreeImage_ConvertToRGBF@4"
FreeImage_ConvertToStandardType%(src,scale_linear):"_FreeImage_ConvertToStandardType@8"
FreeImage_ConvertToType%(src,dst_type,scale_linear):"_FreeImage_ConvertToType@12"
 ;tone mapping operators
FreeImage_ToneMapping%(dib,tmo,first_param_dlo,first_param_dhi,second_param_dlo,second_param_dlo):"_FreeImage_ToneMapping@24"
FreeImage_TmoDrago03%(src,gamma_dlo,gamma_dhi,exposure_dlo,exposure_dhi):"_FreeImage_TmoDrago03@20"
FreeImage_TmoReinhard05%(src,intensity_dlo,intensity_dhi,contrast_dlo,contrast_dhi):"_FreeImage_TmoReinhard05@20"
FreeImage_TmoFattal02%(src,color_saturation_dlo,color_saturation_dhi,attenuation_dlo,attenuation_dhi):"_FreeImage_TmoFattal02@20"

;ZLib Interface
FreeImage_ZLibCompress%(target*,target_size,source*,source_size):"_FreeImage_ZLibCompress@16"
FreeImage_ZLibUncompress%(target*,target_size,source*,source_size):"_FreeImage_ZLibUncompress@16"
FreeImage_ZLibGZip%(target*,target_size,source*,source_size):"_FreeImage_ZLibGZip@16"
FreeImage_ZLibGUnzip%(target*,target_size,source*,source_size):"_FreeImage_ZLibGUnzip@16"
FreeImage_ZLibCRC32%(crc,source*,source_size):"_FreeImage_ZLibCRC32@12"

;Metadata Routines
 ;tag creation / destruction
FreeImage_CreateTag%():"_FreeImage_CreateTag@0"
FreeImage_DeleteTag(tag):"_FreeImage_DeleteTag@4"
FreeImage_CloneTag%(tag):"_FreeImage_CloneTag@4"
 ;tag getters and setters
FreeImage_GetTagKey$(tag):"_FreeImage_GetTagKey@4"
FreeImage_GetTagDescription$(tag):"_FreeImage_GetTagDescription@4"
FreeImage_GetTagID%(tag):"_FreeImage_GetTagID@4"
FreeImage_GetTagType%(tag):"_FreeImage_GetTagType@4"
FreeImage_GetTagCount%(tag):"_FreeImage_GetTagCount@4"
FreeImage_GetTagLength%(tag):"_FreeImage_GetTagLength@4"
FreeImage_GetTagValue%(tag):"_FreeImage_GetTagValue@4"
FreeImage_SetTagKey%(tag,key$):"_FreeImage_SetTagKey@8"
FreeImage_SetTagDescription%(tag,description$):"_FreeImage_SetTagDescription@8"
FreeImage_SetTagID%(tag,id):"_FreeImage_SetTagID@8"
FreeImage_SetTagType%(tag,type):"_FreeImage_SetTagType@8"
FreeImage_SetTagCount%(tag,count):"_FreeImage_SetTagCount@8"
FreeImage_SetTagLength%(tag,length):"_FreeImage_SetTagLength@8"
FreeImage_SetTagValue%(tag,value):"_FreeImage_SetTagValue@8"
 ;iterator
FreeImage_FindFirstMetadata%(model,dib,tag):"_FreeImage_FindFirstMetadata@12"
FreeImage_FindNextMetadata%(mdhandle,tag):"_FreeImage_FindNextMetadata@8"
FreeImage_FindCloseMetadata(mdhandle):"_FreeImage_FindCloseMetadata@4"
 ;metadata setter and getter
FreeImage_SetMetadata%(model,dib,key$,tag):"_FreeImage_SetMetadata@16"
FreeImage_GetMetadata%(model,dib,key$,tag):"_FreeImage_GetMetadata@16"
 ;helpers
FreeImage_GetMetadataCount%(model,dib):"_FreeImage_GetMetadataCount@8"
 ;tag to C string conversion
FreeImage_TagToString$(model,tag,Make$):"_FreeImage_TagToString@12"

;Image Manipulation Toolkit
 ;rotation and flipping
FreeImage_RotateClassic%(dib,angle_dlo,angle_dhi):"_FreeImage_RotateClassic@12"
FreeImage_RotateEx%(dib,angle_dlo,angle_dhi,x_shift_dlo,x_shift_dhi,y_shift_dlo,y_shift_dhi,x_origin_dlo,x_origin_dhi,y_origin_dlo,y_origin_dhi,use_mask):"_FreeImage_RotateEx@48"
FreeImage_FlipHorizontal%(dib):"_FreeImage_FlipHorizontal@4"
FreeImage_FlipVertical%(dib):"_FreeImage_FlipVertical@4"
FreeImage_JPEGTransform%(src_file$,dst_file$,operation,perfect):"_FreeImage_JPEGTransform@16"
 ;upsampling / downsampling
FreeImage_Rescale%(dib,dst_width,dst_height,filter):"_FreeImage_Rescale@16"
FreeImage_MakeThumbnail%(dib,max_pixel_size,convert):"_FreeImage_MakeThumbnail@12"
 ;color manipulation routines (point operations)
FreeImage_AdjustCurve%(dib,LUT*,channel):"_FreeImage_AdjustCurve@12"
FreeImage_AdjustGamma%(dib,gamma_dlo,gamma_dhi):"_FreeImage_AdjustGamma@12"
FreeImage_AdjustBrightness%(dib,percentage_dlo,percentage_dhi):"_FreeImage_AdjustBrightness@12"
FreeImage_AdjustContrast%(dib,percentage_dlo,percentage_dhi):"_FreeImage_AdjustContrast@12"
FreeImage_Invert%(dib):"_FreeImage_Invert@4"
FreeImage_GetHistogram%(dib,histo*,channel):"_FreeImage_GetHistogram@12"
FreeImage_GetAdjustColorsLookupTable%(LUT*,brightness_dlo,brightness_dhi,contrast_dlo,contrast_dhi,gamma_dlo,gamma_dhi,invert):"_FreeImage_GetAdjustColorsLookupTable@32"
FreeImage_AdjustColors%(dib,brightness_dlo,brightness_dhi,contrast_dlo,contrast_dhi,gamma_dlo,gamma_dhi,invert):"_FreeImage_AdjustColors@32"
FreeImage_ApplyColorMapping%(dib,srccolors*,dstcolors*,count,ignore_alpha,swap):"_FreeImage_ApplyColorMapping@24"
FreeImage_SwapColors%(dib,color_a*,color_b*,ignore_alpha):"_FreeImage_SwapColors@16"
FreeImage_ApplyPaletteIndexMapping%(dib,srcindices*,dstindices*,count,swap):"_FreeImage_ApplyPaletteIndexMapping@20"
FreeImage_SwapPaletteIndices%(dib,index_a*,index_b*):"_FreeImage_SwapPaletteIndices@12"
 ;channel processing routines
FreeImage_GetChannel%(dib,channel):"_FreeImage_GetChannel@8"
FreeImage_SetChannel%(dib,dib8,channel):"_FreeImage_SetChannel@12"
FreeImage_GetComplexChannel%(src,channel):"_FreeImage_GetComplexChannel@8"
FreeImage_SetComplexChannel%(dst,src,channel):"_FreeImage_SetComplexChannel@12"
 ;copy / paste / composite routines
FreeImage_Copy%(dib,left,top,right,bottom):"_FreeImage_Copy@20"
FreeImage_Paste%(dst,src,left,top,alpha):"_FreeImage_Paste@20"
FreeImage_Composite%(fg,useFileBkg,appBkColor*,bg):"_FreeImage_Composite@16"
FreeImage_JPEGCrop%(src_file$,dst_file$,left,top,right,bottom):"_FreeImage_JPEGCrop@24"
FreeImage_PreMultiplyWithAlpha%(dib):"_FreeImage_PreMultiplyWithAlpha@4"
 ;miscellaneous algorithms
FreeImage_MultigridPoissonSolver%(Laplacian,ncycle):"_FreeImage_MultigridPoissonSolver@8"

Comments

markcw
(Posted 21 years ago)
FreeImage can load these file formats:
bmp, cut, dds, gif, hdr, ico, iff, jpg, koa, mng, pbm, pcd, pcx, pgm, png, ppm, psd, ras, tga, tif, wap, xbm, xpm

FreeImage can save these file formats:
bmp, gif, hdr, ico, jpg, pbm, pgm, png, ppm, tga, tif, wap, xpm

Note: some formats need to be in the correct structure before they will save eg. i couldn't load bmp then save ico, but could load ico then save ico.

Here are the examples for the FreeImage module.

FiLoadImage.bb
;FiLoadImage

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

image = FiLoadImage("spark.bmp") ;Load image

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "image = "+image

 Flip
Wend
End


FiSaveImage.bb
;FiSaveImage

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

filein$ = "spark.bmp"
fileout$ = "test.png"

image = FiLoadImage(filein$)  ;Load image

FiSaveImage(image, fileout$) ;Save image to file

FreeImage image ;Free old image

image = FiLoadImage(fileout$) ;Load image from new file

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "image = "+image+" fileout$ = "+fileout$
 Text 0, 12, "File was loaded and saved"

 Flip
Wend
End


FiRead.bb
;FiRead

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("spark.bmp") ;Load bitmap

image = FiRead(bitmap) ;Read bitmap to image

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "bitmap = "+bitmap+" image = "+image

 Flip
Wend
End


FiSave.bb
;FiSave

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("spark.bmp") ;Load bitmap

FiSave(bitmap, "test.jpg") ;Save bitmap to file

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 Text 0, 0, "bitmap = "+bitmap
 Text 0, 12, "File was loaded and saved"

 Flip
Wend
End


FiWrite.bb
;FiWrite

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

image = FiLoadImage("spark.bmp")

bitmap = FiWrite(image) ;Write image to bitmap

FiSave(bitmap, "test.png") ;Save bitmap to file

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "image = "+image+" bitmap = "+bitmap
 Text 0, 12, "File was loaded and saved"

 Flip
Wend
End


FiLoadAnimImage.bb
;FiLoadAnimImage

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

image = FiLoadAnimImage("hat.gif") ;Load anim image, tif/ico/gif

frames = FiAnimFrames("hat.gif") ;Get number of frames

settime = MilliSecs() ;Init timer

While Not KeyHit(1)
 Cls

 gettime = MilliSecs() ;Update timer
 If gettime - settime > 500 ;Frame speed
  settime = gettime
  frame = frame + 1
  If frame >= frames Then frame = 0 ;Loop
 EndIf

 DrawImage image, MouseX(), MouseY(), frame ;Draw anim image
 Text 0, 0, "image = "+image+" frames = "+frames+" frame = "+frame

 Flip
Wend
End


FiSaveAnimImage.bb
;FiSaveAnimImage

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

filein$ = "hat.gif"
fileout$ = "test.gif"

image = FiLoadAnimImage(filein$) ;Load anim image, tif/ico/gif

frames = FiAnimFrames(filein$) ;Get number of frames

FiSaveAnimImage(image, fileout$, frames)

FreeImage image ;Free old anim image

image = FiLoadAnimImage(fileout$) ;Load anim image from new file

settime = MilliSecs() ;Init timer

While Not KeyHit(1)
 Cls

 gettime = MilliSecs() ;Update timer
 If gettime - settime > 500 ;Frame speed
  settime = gettime
  frame = frame + 1
  If frame >= frames Then frame = 0 ;Loop
 EndIf

 DrawImage image, MouseX(), MouseY(), frame ;Draw anim image
 Text 0, 0, "image = "+image+" fileout$ = "+fileout$+" frames = "+frames
 Text 0, 12, "File was loaded and saved"

 Flip
Wend
End


FiLoadFromBank.bb
;FiLoadFromBank

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bank = FiBankFromFile("spark.bmp") ;Read file to bank

bitmap = FiLoadFromBank(bank) ;Load bitmap from bank

image = FiRead(bitmap) ;Read bitmap to image

FreeBank bank ;Free bank

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "bitmap = "+bitmap+" image = "+image

 Flip
Wend
End


FiZlibPack.bb
;FiZlibPack

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

file1$ = "hat.gif"
file2$ = "spark.bmp"
datfile$ = "zlib.dat"

FiZlibPack(file1$, datfile$) ;Save to compressed data file
FiZlibPack(file2$, datfile$)

image1 = FiZlibLoadImage(file1$, datfile$) ;Load images from data file
image2 = FiZlibLoadImage(file2$, datfile$)

While Not KeyHit(1)
 Cls

 DrawImage image1, 50, 50 ;Draw the images
 DrawImage image2, MouseX(), MouseY()
 Text 0, 0,"file1$ = "+file1$+" file2$ = "+file2$
 Text 0, 12, "Files were compressed and uncompressed"

 Flip
Wend
End


FiGZip.bb
;FiGZip

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

file1$ = "hat.gif"
file2$ = "spark.bmp"
datfile$ = "gzip.dat"

FiGZip(file1$, datfile$) ;Save to compressed data file
FiGZip(file2$, datfile$)

image1 = FiGZipLoadImage(file1$, datfile$) ;Load images from data file
image2 = FiGZipLoadImage(file2$, datfile$)

While Not KeyHit(1)
 Cls

 DrawImage image1, 50, 50 ;Draw the images
 DrawImage image2, MouseX(), MouseY()
 Text 0, 0,"file1$ = "+file1$+" file2$ = "+file2$
 Text 0, 12, "Files were compressed and uncompressed"

 Flip
Wend
End


FiLoadFromMemory.bb
;FiLoadFromMemory

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

stream = FiSaveToMemory("hat.gif") ;Save bitmap to memory

bitmap = FiLoadFromMemory(stream) ;Load bitmap from memory stream

image = FiRead(bitmap) ;Read bitmap to image

size = FiMemorySize(stream) ;Get file size from memory stream

FiCloseMemory(stream) ;Free memory stream

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "stream = "+stream+" bitmap = "+bitmap+" size = "+size

 Flip
Wend
End


FiRescale.bb
;FiRescale

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

scale = 200 ;Scale as percentage
filter = 4 ;0=box 1=bilinear 2=bspline 3=bicubic 4=catmullrom 5=lanczos

oldbmp = FiLoad("spark.bmp") ;Load bitmap

newbmp = FiRescale(oldbmp, scale, filter) ;Rescale bitmap

image = FiRead(newbmp) ;Read scaled bitmap to image

FiUnload(oldbmp) ;Free bitmaps
FiUnload(newbmp)

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "scale = "+scale+" filter = "+filter+" image = "+image

 Flip
Wend
End


FiRotateClassic.bb
;FiRotateClassic

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

oldbmp = FiLoad("spark.bmp") ;Load bitmap

angle# = 45 ;Angle, negative is anti-clockwise

newbmp = FiRotateClassic(oldbmp, angle#)

image = FiRead(newbmp) ;Read bitmap to image

FiUnload(oldbmp) ;Free bitmaps
FiUnload(newbmp)

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "angle# = "+angle#+" image = "+image

 Flip
Wend
End


FiRotateClassicEx.bb
;FiRotateClassicEx

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

oldbmp = FiLoad("spark.bmp") ;Load bitmap

angle# = 45 ;Angle, negative is anti-clockwise
bgcolor = $ffffff ;Optional background color, default is black

newbmp = FiRotateClassicEx(oldbmp, angle#, bgcolor)

image = FiRead(newbmp) ;Read bitmap to image

FiUnload(oldbmp) ;Free bitmaps
FiUnload(newbmp)

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "angle# = "+angle#+" bgcolor = "+Hex(bgcolor)+" image = "+image

 Flip
Wend
End


FiAdjustGamma.bb
;FiAdjustGamma

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("hat.gif") ;Load bitmap

gamma# = 2.5 ;Gamma 0.1..10.0

FiAdjustGamma(bitmap, gamma#)

image = FiRead(bitmap) ;Read bitmap to image

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "gamma# = "+gamma#+" image = "+image

 Flip
Wend
End


FiAdjustBrightness.bb
;FiAdjustBrightness

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("hat.gif") ;Load bitmap

brightness#=50 ;Brightness -100..100

FiAdjustBrightness(bitmap, brightness#)

image = FiRead(bitmap) ;Read bitmap to image

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "brightness# = "+brightness#+" image = "+image

 Flip
Wend
End


FiAdjustContrast.bb
;FiAdjustContrast

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("hat.gif") ;Load bitmap

contrast#=-50 ;Contrast -100..100

FiAdjustContrast(bitmap, contrast#)

image = FiRead(bitmap) ;Read bitmap to image

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "contrast# = "+contrast#+" image = "+image

 Flip
Wend
End


FiAdjustIntensity.bb
;FiAdjustIntensity

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

bitmap = FiLoad("hat.gif") ;Load bitmap

intensity#=50 ;Intensity -100..100

FiAdjustIntensity(bitmap, intensity#)

image = FiRead(bitmap) ;Read bitmap to image

FiUnload(bitmap) ;Free bitmap

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "intensity# = "+intensity#+" image = "+image

 Flip
Wend
End


FiMemoryToFile.bb
;FiMemoryToFile

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

stream = FiSaveToMemory("hat.gif") ;Save bitmap to memory

fileout$ = "test.gif" ;Function assumes the file extension is known

FiMemoryToFile(stream, fileout$) ;Save memory stream to file

image = FiLoadImage(fileout$) ;Load image

FiCloseMemory(stream) ;Free memory stream

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0, 0, "stream = "+stream+" fileout$ = "+fileout$

 Flip
Wend
End


FiCopyToClipboard.bb
;FiCopyToClipboard

Include "freeimage.bb" ;FreeImage Module

Graphics 640, 480, 0, 2
SetBuffer BackBuffer()

oldbmp = FiLoad("hat.gif") ;Load bitmap

FiCopyToClipboard(oldbmp) ;Copy bitmap to clipboard

newbmp = FiPasteFromClipboard() ;Paste clipboard to new bitmap

width = FiGetWidth(newbmp) ;Get bitmap info
height = FiGetHeight(newbmp)
bpp = FiGetBPP(newbmp)

image = FiRead(newbmp) ;Read bitmap to image

FiUnload(oldbmp) ;Free bitmaps
FiUnload(newbmp)

While Not KeyHit(1)
 Cls

 DrawImage image, MouseX(), MouseY() ;Draw the image
 Text 0,0,"Paste the clipboard to an image editor to see the results"
 Text 0,24,"oldbmp = "+oldbmp+" newbmp="+newbmp
 Text 0,36,"width = "+width+" height = "+height+" bpp = "+bpp

 Flip
Wend
End


Wayne
(Posted 21 years ago)
How about loading a Tif, what that look like ?

markcw
(Posted 21 years ago)
it loads an image to memory, but doesn't display it.
i tried to work out how to display them but failed.
they go into memory but i couldn't access the pixel data, so couldn't display them.
to display them, you would have to save first to a format that Blitz can then load.

markcw
(Posted 21 years ago)
well, i surprised myself and have figured out how to display the images loaded without having to save as i suggested above. I would like to credit DJWoodgate for helping me understand how to use banks as type pointers. So now you can read/write to these images in Blitz.

Here is a load, read and draw example, which shows use of the FreeImage_GetPixelColor command.

Edit: see FiRead above.

markcw
(Posted 21 years ago)
I thought i would also add an example of how to use the FreeImage_SetPixelColor command.

Note: Specifying the red/green/blue masks in FreeImage_Allocate is not actually necessary, as readpixelfast determines the order in this case.

Edit: see FiWrite above.

markcw
(Posted 21 years ago)
well, i have written a few more examples for the memory stream commands. I have tested all these commands and the only one i couldn't use was FreeImage_AcquireMemory because it required direct access to memory which Blitz3D doesn't provide.

Here is an example of using FreeImage_LoadFromMemory.

Edit: see FiLoadFromBank above.

markcw
(Posted 21 years ago)
And here is an example of using FreeImage_SaveToMemory.

Edit: see FiSaveToMemory above.

Wayne
(Posted 21 years ago)
can you read and display a Tif file yet?
8)

markcw
(Posted 21 years ago)
yes Wayne, i have tried loading in a tif image with these examples and it works as expected.

markcw
(Posted 21 years ago)
Here is an example of using FreeImage_ZLibCompress and FreeImage_ZLibUncompress.

Edit: see FiZlibPack above.

Wayne
(Posted 21 years ago)
Looking good Mark. I appreciate the code and examples. It really helps people understand and use this great library.

One of my handfull of projects has me investigating the possibility of displaying scanned documents ie TIF, BMP, and JPG. Displaying images so that a user can identify and index the document. The ability to zoom and rotate would also be helpfull.

BMP and JPG seem to be easy but TIF and possibly multi page TIF are a little more involved.

I'm looking at the code you provided and will take a crack at it shortly, but I must finish the S ketch Up => B3d exporter.

Nice work Mark, I appreciate your examples very much.

markcw
(Posted 21 years ago)
Thanks for the feedback Wayne. Now i see what you mean, i've never worked with tif so didn't know it has a multi-page feature.

FreeImage has these commands for multipage files and the rotation and scaling but i haven't looked at these ones yet. I'll see if i can get a working multipage example going then.

markcw
(Posted 21 years ago)
This is an example of using the FreeImage_ZLibGZip and FreeImage_ZLibGUnzip commands. It is identical to use of the standard Zlib compression except for the buffer size.

Edit: see FiGZip above.

markcw
(Posted 21 years ago)
Here is an example of how to load, read and draw an animated image from a multipage bitmap. Only tif, ico and gif files are supported.

Shows how to use FreeImage_OpenMultiBitmap and FreeImage_LockPage.

Edit: see FiLoadAnimImage above.

Wayne
(Posted 21 years ago)
Oustanding work Mark! WORKS GREAT !!
Hey you kicked some ass on this stuff bro.

I can't wait to do some panning , rotating, and zooming.
Congratulations job well done on the TIFF format.

What would really help you out B3d wise Mark ?

markcw
(Posted 21 years ago)
Cool Wayne, glad it is useful to you.

I don't really need any help b3d-wise, but thanks for the offer.

I just decided to work on this library for fun really. :)

markcw
(Posted 21 years ago)
Here is an example of how to write and save an animated image to a multipage bitmap. I couldn't figure out how to save ico, but tif and gif work fine.

Shows how to use FreeImage_OpenMultiBitmap and FreeImage_AppendPage to create new files.

Edit: see FiSaveAnimImage above.

markcw
(Posted 21 years ago)
Here is an example of how to load an image, rescale (or zoom) it and save it to a file. It also reads and draws the rescaled image.

I have also updated the FreeImage_SaveFunction which now converts gif to 8bit palette and pgm to greyscale. These formats won't save to 24bits.

Edit: see FiRescale above.

markcw
(Posted 21 years ago)
Ok, it's a pity but i'm fairly sure all the commands in FreeImage that require a float actually require a double, which is 8 bytes and blitz3d doesn't support this so i was unable to use the FreeImage_RotateClassic command.

But, since i thought it was important to have this command, i translated the source code into blitz3d. On top of this i extended it to allow setting a background color, the actual command always has a black background.

So here is an example of how to use FreeImage to load an image, rotate it and save it to a file. :)

Edit: see FiRotateClassicEx above.

Wayne
(Posted 21 years ago)
I'm trying them all out now. Very nice.

markcw
(Posted 21 years ago)
This is a translation of the FreeImage_AdjustGamma command which also requires a double. Also shows use of FreeImage_AdjustCurve.

Edit: see FiAdjustGamma above.

markcw
(Posted 21 years ago)
This is a translation of FreeImage_AdjustBrightness which also requires a double.

I actually had to [change] this algorithm as the one in the source [was for intensity].

Edit: see FiAdjustBrightness above.

markcw
(Posted 21 years ago)
This is a translation of FreeImage_AdjustContrast which also requires a double.

Edit: see FiAdjustContrast above.

B+man
(Posted 21 years ago)
Wow, great stuff muk, thank you for sharing! ;)

Dabz

markcw
(Posted 21 years ago)
thanks Dabz.

I noticed that the source for FreeImage_AdjustBrightness is actually not wrong but is for intensity, maybe in France it is for brightness. :)

So here is an example of FreeImage_AdjustIntensity.

Edit: see FiAdjustIntensity above.

Wayne
(Posted 21 years ago)
checking it out !

markcw
(Posted 20 years ago)
I read jfk's post on hacking which uses RtlMoveMemory for direct memory access in blitz3d, so now i have a reliable method to use for this example. :)

You need to have a file named "Kernel32.decls" in your "userlibs" folder with these declared.
.lib "Kernel32.dll"

; Memory Management Functions
Api_RtlCopyMemory(Destination,Source*,Length):"RtlMoveMemory"
Api_RtlMoveMemory(Destination*,Source,Length):"RtlMoveMemory"

So here is an example of FreeImage_AcquireMemory using the win32 api.

Edit: see FiMemoryToFile above.

kragoth74
(Posted 20 years ago)
Is there a way to read/write an image from/to the clipboard ?

markcw
(Posted 20 years ago)
hi kragoth74,

i checked the FreeImage docs and it doesn't have commands for the clipboard, so you would need to use a dll for this. I think Snarty had a dll to use the clipboard which he used with his FreeImage decls here on blitzcoder but it doesn't seem to be there any more.

kragoth74
(Posted 20 years ago)
Thank you muk. :-)

markcw
(Posted 20 years ago)
just tidied these examples up a bit, added local variables and took off the "L" in front of them, so they're easier to read and won't cause an error if you happen to use a global with the same name.

markcw
(Posted 20 years ago)
ok, i did a bit of research on bitmaps in the win32 api and found an article on http://www.codeproject.com which was extremely helpful in this.

edit: my first version of these clipboard examples used the api functions getpixel/setpixel to transfer the bitmap as a DFB/DDB. This is bad because it's slow and there is no way to correctly interpret the bits as they are in video memory. I wasn't happy, so i had another search and found another article from the same place about DIBs which led to these much improved examples. :)

You need to have a file named "User32.decls" in your "userlibs" folder with these declared.
.lib "User32.dll"

; Clipboard Functions
Api_CloseClipboard%():"CloseClipboard"
Api_EmptyClipboard%():"EmptyClipboard"
Api_GetClipboardData%(uFormat):"GetClipboardData"
Api_IsClipboardFormatAvailable%(format):"IsClipboardFormatAvailable"
Api_OpenClipboard%(hwnd):"OpenClipboard"
Api_SetClipboardData%(uFormat,hData):"SetClipboardData"

And a file named "Kernel32.decls" in the "userlibs" folder with these declared.
.lib "Kernel32.dll"

; Memory Management Functions
Api_GlobalAlloc%(uFlags,dwBytes):"GlobalAlloc"
Api_GlobalLock%(hMem):"GlobalLock"
Api_GlobalUnlock%(hMem):"GlobalUnlock"
Api_RtlCopyMemory(Destination,Source*,Length):"RtlMoveMemory"
Api_RtlMoveMemory(Destination*,Source,Length):"RtlMoveMemory"

Or you can use the user32.dll decls and kernel32.dll decls.

So here an example of copying a FreeImage bitmap to the clipboard using win32 api.

Edit: see FiCopyToClipboard above.

markcw
(Posted 20 years ago)
And here is an example of pasting the clipboard to a new FreeImage bitmap using the win32 api.

Edit: see FiCopyToClipboard above.

OverDozing
(Posted 19 years ago)
Thank you !
Very Cool stuff

Ked
(Posted 19 years ago)
How would load a bmp, jpg, or png and save to bmp, jpg, or png?

_33
(Posted 19 years ago)
Hello, is there an update on the DECLS file for the newer freeimage DLL 3.10.0 ? Thanks for this markcw, will read through your examples tomorrow! Also I am wondering if freeimage only handles images, or if it can handle video? I saw some comde example on animated GIF, nice!

markcw
(Posted 19 years ago)
Hi, no. I was going to update this anyway so I'll get to work on 3.10 soon. I was going to change the function names to something more useable and create a module. FreeImage only handles images, so no avi, mpeg, etc.

markcw
(Posted 18 years ago)
Ok, I've finished converting this to a module now, so to celebrate I've uploaded a zipped version which you can get here (Freeimage.dll not included):
http://blitzmirror.angelfire.com/

ervin
(Posted 18 years ago)
Ah, excellent.
I'm just curious, as I'm still something of a beginner with B3D... what is the advantage of having converted to a module?

markcw
(Posted 18 years ago)
Well before the module all the functions were in separate files so you had to combine the functions and make your own module, now all you have to do is include the file and you can get on with using the functions.

system4
(Posted 18 years ago)
Yo Mark.. I have to say that you are very awesome.. How do you Mask Images under FreeImage?

Code Archives Forum