mirror of
https://github.com/appgurueu/modlib.git
synced 2024-11-25 16:53:46 +01:00
Add modlib.minetest.encode_png
This commit is contained in:
parent
e5a3f0c9d8
commit
578d504575
@ -6,7 +6,8 @@ for _, value in pairs{
|
|||||||
"raycast",
|
"raycast",
|
||||||
"schematic",
|
"schematic",
|
||||||
"colorspec",
|
"colorspec",
|
||||||
"media"
|
"media",
|
||||||
|
"encode_png",
|
||||||
} do
|
} do
|
||||||
components[value] = value
|
components[value] = value
|
||||||
end
|
end
|
||||||
|
118
minetest/encode_png.lua
Normal file
118
minetest/encode_png.lua
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
if minetest.encode_png then
|
||||||
|
return minetest.encode_png
|
||||||
|
end
|
||||||
|
|
||||||
|
local assert, char, ipairs, insert, concat, floor = assert, string.char, ipairs, table.insert, table.concat, math.floor
|
||||||
|
|
||||||
|
-- TODO move to modlib.bit eventually
|
||||||
|
local bit_xor = bit.xor or function(a, b)
|
||||||
|
local res = 0
|
||||||
|
local bit = 1
|
||||||
|
for _ = 1, 32 do
|
||||||
|
if a % 2 ~= b % 2 then
|
||||||
|
res = res + bit
|
||||||
|
end
|
||||||
|
a = floor(a / 2)
|
||||||
|
b = floor(b / 2)
|
||||||
|
bit = bit * 2
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
local crc_table = {}
|
||||||
|
for i = 0, 255 do
|
||||||
|
local c = i
|
||||||
|
for _ = 0, 7 do
|
||||||
|
if c % 2 > 0 then
|
||||||
|
c = bit_xor(0xEDB88320, floor(c / 2))
|
||||||
|
else
|
||||||
|
c = floor(c / 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
crc_table[i] = c
|
||||||
|
end
|
||||||
|
|
||||||
|
local function encode_png(width, height, data, compression, raw_write)
|
||||||
|
local write = raw_write
|
||||||
|
local function byte(value)
|
||||||
|
write(char(value))
|
||||||
|
end
|
||||||
|
local function _uint(value)
|
||||||
|
local div = 0x1000000
|
||||||
|
for _ = 1, 4 do
|
||||||
|
byte(floor(value / div) % 0x100)
|
||||||
|
div = div / 0x100
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function uint(value)
|
||||||
|
assert(value < 2^31)
|
||||||
|
_uint(value)
|
||||||
|
end
|
||||||
|
local chunk_content
|
||||||
|
local function chunk_write(text)
|
||||||
|
insert(chunk_content, text)
|
||||||
|
end
|
||||||
|
local function chunk(type)
|
||||||
|
chunk_content = {}
|
||||||
|
write = chunk_write
|
||||||
|
write(type)
|
||||||
|
end
|
||||||
|
local function end_chunk()
|
||||||
|
write = raw_write
|
||||||
|
local chunk_len = 0
|
||||||
|
for i = 2, #chunk_content do
|
||||||
|
chunk_len = chunk_len + #chunk_content[i]
|
||||||
|
end
|
||||||
|
uint(chunk_len)
|
||||||
|
write(concat(chunk_content))
|
||||||
|
local chunk_crc = 0xFFFFFFFF
|
||||||
|
for _, text in ipairs(chunk_content) do
|
||||||
|
for i = 1, #text do
|
||||||
|
chunk_crc = bit_xor(crc_table[bit_xor(chunk_crc % 0x100, text:byte(i))], floor(chunk_crc / 0x100))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_uint(bit_xor(chunk_crc, 0xFFFFFFFF))
|
||||||
|
end
|
||||||
|
-- Signature
|
||||||
|
write"\137\80\78\71\13\10\26\10"
|
||||||
|
chunk"IHDR"
|
||||||
|
uint(width)
|
||||||
|
uint(height)
|
||||||
|
-- Always use bit depth 8
|
||||||
|
byte(8)
|
||||||
|
-- Always use color type "truecolor with alpha"
|
||||||
|
byte(6)
|
||||||
|
-- Compression method: deflate
|
||||||
|
byte(0)
|
||||||
|
-- Filter method: PNG filters
|
||||||
|
byte(0)
|
||||||
|
-- No interlace
|
||||||
|
byte(0)
|
||||||
|
end_chunk()
|
||||||
|
chunk"IDAT"
|
||||||
|
local data_bytestring = {}
|
||||||
|
for y = 0, height - 1 do
|
||||||
|
local base = y * width
|
||||||
|
insert(data_bytestring, "\0")
|
||||||
|
for x = 1, width do
|
||||||
|
local color_int = data[base + x]
|
||||||
|
local a = floor(color_int / 0x1000000) % 0x100
|
||||||
|
local r = floor(color_int / 0x10000) % 0x100
|
||||||
|
local g = floor(color_int / 0x100) % 0x100
|
||||||
|
local b = color_int % 0x100
|
||||||
|
insert(data_bytestring, char(r, g, b, a))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
write(minetest.compress(concat(data_bytestring), "deflate", compression))
|
||||||
|
end_chunk()
|
||||||
|
chunk"IEND"
|
||||||
|
end_chunk()
|
||||||
|
end
|
||||||
|
|
||||||
|
(...).encode_png = function(width, height, data, compression)
|
||||||
|
local rope = {}
|
||||||
|
encode_png(width, height, data, compression or 9, function(text)
|
||||||
|
insert(rope, text)
|
||||||
|
end)
|
||||||
|
return concat(rope)
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user