Saving functions into images

Hey all! My newest project, I was trying to sneakily hide a function, and I came up with this! It saves a function into an image and can decode an image into a function!


function setup( )
    getImage("https://dl.dropboxusercontent.com/s/3s8jnuew7a5rxjj/HelloWorld.png?dl=1&token_hash=AAEi-RKiHv52zHbfWYgA2oBA8kxn6w_g2ctMtrkXh5gqlw") -- comment this line and uncomment the following two lines to see how to use the functions
    --[[
    spr = encode(function () print("Testing Testing 1 2 3") end)
    decode(spr)()
    ]]
end

function draw( )
    background(255)
    noSmooth()
    if spr then sprite(spr, WIDTH / 2, HEIGHT / 2, WIDTH - 100, HEIGHT - 100) end
end

function functionToTable( f )
    local dump = string.dump( f )
    local chars = {}
    for c in dump:gmatch( "." ) do
        table.insert( chars, string.byte( c ) )
    end
    
    return chars
end

-- Referenced from code by dave1707

function encode( f )
    local t = functionToTable(f)
    local l = #t
    local s = math.ceil(l / 3) + 1 -- + 1 for size information
    local w = math.ceil(math.sqrt(s))
    local h = math.ceil(s / w)
    local img = image(w, h)
    setContext(img)
        background(0)
    setContext()
    local e = l % 256
    local e1 = (math.floor(l / 256)) % 256
    local e2 = (math.floor(l / 256 / 256)) % 256
    img:set(1, 1, e2, e1, e, 255)
    for i = 2, s do
        local x, y = (i - 1) % w + 1, math.ceil(i / w)
        local r, g, b
        r = t[(i - 2) * 3 + 1] or 0
        g = t[(i - 2) * 3 + 2] or 0
        b = t[(i - 2) * 3 + 3] or 0
        img:set(x, y, r, g, b, 255)
    end
    
    return img
end

function decode( img )
    local w, h = img.width, img.height
    
    local e2, e1, e = img:get(1, 1)
    
    local l = e2 * 256 * 256 + e1 * 256 + e
    local s = math.ceil(l / 3) + 1
    local t = {}
    
    for i = 2, s do
        local x, y = (i - 1) % w + 1, math.ceil(i / w)
        local r, g, b = img:get(x, y)
        table.insert(t, r)
        table.insert(t, g)
        table.insert(t, b)
    end
    for i = 1, #t - l do
        table.remove(t)
    end
    
    local str = ""
    
    for i, b in ipairs(t) do
        str = str .. string.char(b)
    end
    
    return loadstring(str)
end

function getImage(link)
    http.request(link, gotImage)
    print("Downloading function image...")
end

function gotImage(img)
    print"Downloaded function image... Calling function"
    spr = img
    decode(spr)()
end

@Jordan Something like this was done in a previous discussion long ago. I tried to find it, but I wasn’t successful because I don’t remember what it was under. The reason I remember this is because I also made a comment about it back them. I’m not sure if you’re aware of this, but the whole program goes in the image, not just your “test” function. So I’m not sure if you can get just a single function in the image and have it work.

I have used images to store data a number of times (as we don’t have files and folders). Very handy.

@Ignatz But we do have files. Depending on the name you give the file, you may or may not see it in Codeas Documents or Dropbox folder. But you will see it if it’s in the Dropbox folder and it gets sync’d to the Dropbox app.

@Ignatz I used images to store thing also before I figured out how to use actual files. I have a dictionary of 300,249 words stored as an image. The image size is 1025x1025.

@Jordan I found the discussion I was thinking about. What I was thinking of is towards the end of the discussion.

http://twolivesleft.com/Codea/Talk/discussion/comment/25541