ImageData FFI access for floating point formats

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
eaaakb
Prole
Posts: 5
Joined: Sun Dec 22, 2024 10:46 am

ImageData FFI access for floating point formats

Post by eaaakb »

I’ve have some success in accessing and modifying ImageData using FFI with fixed point formats like r16 but seem not to be able to do so correctly with formats like r32f. Am I wrong to assume that the ImageData conforms to the usual IEEE 754 format? And what about r16f?

This is for an application where mapPixel() and getPixel() are simply too slow. I could provide some code if needed, but I hope the above is clear without it.

Much appreciate any help.
User avatar
zorg
Party member
Posts: 3480
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: ImageData FFI access for floating point formats

Post by zorg »

As far as i know, it should use IEEE; which format did you try with FFI though? single or double precision?
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
eaaakb
Prole
Posts: 5
Joined: Sun Dec 22, 2024 10:46 am

Re: ImageData FFI access for floating point formats

Post by eaaakb »

Thanks so much for your response.

Here's a little test program which generates two red shaded squares, one generated with 'r16' ImageData, the other with 'r32f'.

It works fine, so single precision IEEE 754 'float' matches 'r32f'.

The question is how to achieve this for 'r16f' image data, given that I can't find a native half-precision float type?

I suppose a workaround would be to generate a 'r32f' image and render it to a 'r16f' canvas... bit of a kludge!

Code: Select all

-- test ImageData

local ffi = require "ffi"

local N = 100
local N2 = N * N

local r16  = love.image.newImageData(N, N, "r16")
local r16f = love.image.newImageData(N, N, "r16f")  -- how to do this one??
local r32f = love.image.newImageData(N, N, "r32f")

local c16, c16f, c32f

function love.load(arg)
 
  -- r16 format
  local p16 = r16: getFFIPointer()
  local u16 = ffi.cast("uint16_t*", p16)
  for i = 0, N2 - 1 do
    u16[i] = 65536 * i / N2
  end  
  c16 = love.graphics.newImage(r16)  

  -- r32f format
  local p32f = r32f: getFFIPointer()
  local f32 = ffi.cast("float*", p32f)
  for i = 0, N2 - 1 do
    f32[i] = i / N2
  end  
  c32f = love.graphics.newImage(r32f)  

end

function love.update(dt)
end

function love.draw()
  local c = 0.3
  love.graphics.clear(c,c,c, 1)
  love.graphics.draw(c16, 100,100)
  love.graphics.draw(c32f, 300,100)
end

-----
User avatar
pgimeno
Party member
Posts: 3713
Joined: Sun Oct 18, 2015 2:58 pm

Re: ImageData FFI access for floating point formats

Post by pgimeno »

You'll have to build the float yourself.

These functions work, more or less (note: use int16_t * instead of uint16_t * to access the pixels as FFI data):

Code: Select all

local bit = require('bit')
local AND = bit.band
local SHL = bit.lshift
local SHR = bit.rshift
local ldexp = math.ldexp
local frexp = math.frexp
local min = math.min
local max = math.max
local floor = math.floor

local function sgn(x)
  return max(min(x * 1e300 * 1e300, 1), -1)
  -- note: you can remove one * 1e300 if you're not going to handle
  -- numbers between 5e-324 and 1e-300
end

local function int16_to_f16(a)
  local s = sgn(a)
  return ldexp(AND(a, 1023) + 1024, AND(SHR(a, 10), 31) - 25) * s
end

local function f16_to_int16(a)
    if a == 0 then return 0 end
    local e
    local s = sgn(a)
    a, e = frexp(a * s)

    return floor(a * 2048 - 1024) + SHL(max(0, min(e + 14, 31)), 10) + min(s * 32768, 0)
end
User avatar
eaaakb
Prole
Posts: 5
Joined: Sun Dec 22, 2024 10:46 am

Re: ImageData FFI access for floating point formats

Post by eaaakb »

Thanks for that! Pretty much covers all my needs on this issue.

This is for my astro image processing app:
https://github.com/akbooer/Lovell

Much appreciated.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 9 guests