Page 1 of 2

API questions

Posted: Tue Aug 15, 2017 2:27 pm
by Santos
Sometimes I get confused by things in the API, so here's a thread with questions in it.

I'm a bit slow so please forgive the dumb questions.


Question number 1:

To the best of my understanding, the second argument of love.math.compress/decompress is the compression format, however when I pass different types to compress and decompress it seems to decompress fine, which is surprising.

Code: Select all

function love.load()
    a = love.math.compress('This is a test', 'gzip')
    b = love.math.decompress(a, 'zlib')
end

function love.draw()
    love.graphics.print(b)
end
From looking at LOVE's source code, I'm wondering, is the LZ4 format always being used?

Code: Select all

int w_compress(lua_State *L)
{
	const char *fstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
	Compressor::Format format = Compressor::FORMAT_LZ4;


Question number 2:

Why don't love.graphics.newText and Text:set/setf have transformation (position/rotation/scaling/etc.) options, like Text:add/addf and love.graphics.print/printf do?

Slime has kindly explained previously that Text:set/setf is for when you want a single Text object to contain a single piece of text that doesn't have its own local transformation, but I'm wondering, what's this use case for? Or, why not be able to have a local transformation since it could be possible? If one didn't want the text to have a transformation couldn't they just leave it off?


I predict there will be more questions to come...

Thanks for reading! :)

Re: API questions

Posted: Tue Aug 15, 2017 3:05 pm
by slime
Santos wrote:
Tue Aug 15, 2017 2:27 pm
Question number 1:

To the best of my understanding, the second argument of love.math.compress/decompress is the compression format, however when I pass different types to compress and decompress it seems to decompress fine, which is surprising.
decompress only uses a format argument when you pass it a string. When you pass it a CompressedData, it uses the format obtained via that object.
Santos wrote:
Tue Aug 15, 2017 2:27 pm
From looking at LOVE's source code, I'm wondering, is the LZ4 format always being used?
Nope, look a line or two below what you quoted. :)

Santos wrote:
Tue Aug 15, 2017 2:27 pm
Why don't love.graphics.newText and Text:set/setf have transformation (position/rotation/scaling/etc.) options, like Text:add/addf and love.graphics.print/printf do?

Slime has kindly explained previously that Text:set/setf is for when you want a single Text object to contain a single piece of text that doesn't have its own local transformation, but I'm wondering, what's this use case for? Or, why not be able to have a local transformation since it could be possible? If one didn't want the text to have a transformation couldn't they just leave it off?
love.graphics.draw(text, ...) has transformation arguments.

A Text object can be used in two ways:

- A simple container for a single string of text. This is just like storing a string and calling love.graphics.print(str, ...), but it stores the vertex data for the glyphs instead of just the bytes of the string, so it doesn't have to do as much work when drawing it.

- A 'sprite batch' for text. This is basically like a SpriteBatch in that you'd add a bunch of different strings of text to the Text object, potentially at different local transformations, and then you'd draw the text object once using love.graphics.draw(text), likely without any transformation arguments there. This can improve performance due to batching.

Re: API questions

Posted: Tue Aug 15, 2017 4:21 pm
by Santos
Slime, thank you so much, that all makes perfect sense.

Code: Select all

a = love.math.compress('test', 'gzip')
print(a:type())
print(a:getFormat())
b = love.math.decompress(a)
print(b)
c = love.math.decompress(a:getString(), 'gzip')
print(c)
Output:

Code: Select all

CompressedData
gzip
test
test
(And I learned about StringMap::find! :P)


And the Text object API now make sense to me, thanks for the explanation! :)

Re: API questions

Posted: Wed Aug 16, 2017 9:18 am
by Santos
(Excuse the double post!)

Question number 3:

How can an ImageData be compressed and decompressed and remade into an Image?

I naively tried this:

imagedatacompress.love
(6.96 KiB) Downloaded 26 times

Code: Select all

function love.load()
    imagedata = love.image.newImageData('image.png')
    compressed = love.math.compress(imagedata)
    decompressed = love.math.decompress(compressed)
    filedata = love.filesystem.newFileData(decompressed, 'test.png')
    image = love.graphics.newImage(filedata)
end

function love.draw()
    love.graphics.draw(image)
end

Code: Select all

Error

main.lua:6: Could not decode file 'test.png' to ImageData: unsupported file format


Traceback

[C]: in function 'newImageData'
main.lua:6: in function 'load'
[C]: in function 'xpcall'

Re: API questions

Posted: Wed Aug 16, 2017 11:12 am
by zorg
You can not give love.graphics.newImage a FileData object, the wiki says so.
You can only do that with ImageData's constructor, so that the created ImageData can be passed into newImage.

Re: API questions

Posted: Wed Aug 16, 2017 11:24 am
by Santos
Thank you zorg, however the wiki is incomplete!

Code: Select all

function love.load()
    filedata = love.filesystem.newFileData('image.png')
    image = love.graphics.newImage(filedata)
end

function love.draw()
    love.graphics.draw(image)
end
I had an idea related to this in a thread entitled Wiki proposal: merge constructor variants differing only by filepath/File/FileData argument

Re: API questions

Posted: Wed Aug 16, 2017 1:01 pm
by slime
Santos wrote:
Wed Aug 16, 2017 9:18 am
How can an ImageData be compressed and decompressed and remade into an Image?

Code: Select all

imagedata = love.image.newImageData('image.png')
width, height = imagedata:getDimensions()
compressed = love.math.compress(imagedata)

decompressed = love.math.decompress(compressed)
imagedata = love.image.newImageData(width, height, decompressed)

image = love.graphics.newImage(imagedata)

Re: API questions

Posted: Thu Aug 17, 2017 8:46 am
by Santos
Cool, thanks again slime! :)

Question number 4:

Can a SoundData object be compressed and decompressed and remade?

Based on how it works with ImageData I imagined love.sound.newSoundData might undocumentedly work like this:

Code: Select all

function love.load()
    sounddata = love.sound.newSoundData('sound.wav')

    sampleCount = sounddata:getSampleCount()
    sampleRate = sounddata:getBitDepth()
    bitDepth = sounddata:getBitDepth()
    channels = sounddata:getChannels()

    compressed = love.math.compress(sounddata)
    decompressed = love.math.decompress(compressed)

    sounddata2 = love.sound.newSoundData(sampleCount, sampleRate, bitDepth, channels, decompressed)

    for i = 0, sounddata2:getSampleCount() - 1 do
        if sounddata2:getSample(i) ~= 0 then
            print('SoundData contains non-zero value')
        end
    end

    source = love.audio.newSource(sounddata2)
end

function love.keypressed()
    source:clone():play()
end
But the SoundData was all zeros. After looking at wrap_Sound.cpp, this is no surprise.

Re: API questions

Posted: Fri Sep 22, 2017 11:45 am
by Santos
(Excuse the double post again!)

The description for love.math.decompress says it can accept a previously compressed Data object along with a CompressedDataFormat as arguments. I'm confused as to when this would be possible.

What other types of Data objects, other than CompressedData, can be decompressed with love.math.decompress?

Re: API questions

Posted: Fri Sep 22, 2017 11:49 am
by slime
Any. For example you could copy the contents of a CompressedData object to a new FileData, and then pass the FileData in along with the format.