forked from VoxeLibre/VoxeLibre
Add updated tga_encoder
This commit is contained in:
parent
63d4e57a8d
commit
1eaf662833
|
@ -1,7 +1,5 @@
|
||||||
tga_encoder = {}
|
tga_encoder = {}
|
||||||
|
|
||||||
local LUA_ARGS_LIMIT = 1000
|
|
||||||
|
|
||||||
local image = setmetatable({}, {
|
local image = setmetatable({}, {
|
||||||
__call = function(self, ...)
|
__call = function(self, ...)
|
||||||
local t = setmetatable({}, {__index = self})
|
local t = setmetatable({}, {__index = self})
|
||||||
|
@ -11,8 +9,7 @@ local image = setmetatable({}, {
|
||||||
})
|
})
|
||||||
|
|
||||||
function image:constructor(pixels)
|
function image:constructor(pixels)
|
||||||
self.bytes = {}
|
self.data = ""
|
||||||
self.chunks = {self.bytes}
|
|
||||||
self.pixels = pixels
|
self.pixels = pixels
|
||||||
self.width = #pixels[1]
|
self.width = #pixels[1]
|
||||||
self.height = #pixels
|
self.height = #pixels
|
||||||
|
@ -20,87 +17,59 @@ function image:constructor(pixels)
|
||||||
self:encode()
|
self:encode()
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:insert(byte)
|
|
||||||
table.insert(self.bytes, byte)
|
|
||||||
if #self.bytes == LUA_ARGS_LIMIT then
|
|
||||||
self.bytes = {}
|
|
||||||
table.insert(self.chunks, self.bytes)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function image:littleendian(size, value)
|
|
||||||
for i = 1, size do
|
|
||||||
local byte = value % 256
|
|
||||||
value = value - byte
|
|
||||||
value = value / 256
|
|
||||||
self:insert(byte)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function image:encode_colormap_spec()
|
function image:encode_colormap_spec()
|
||||||
-- first entry index
|
self.data = self.data
|
||||||
self:littleendian(2, 0)
|
.. string.char(0, 0) -- first entry index
|
||||||
-- number of entries
|
.. string.char(0, 0) -- number of entries
|
||||||
self:littleendian(2, 0)
|
.. string.char(0) -- bits per pixel
|
||||||
-- number of bits per pixel
|
|
||||||
self:insert(0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:encode_image_spec()
|
function image:encode_image_spec()
|
||||||
-- X- and Y- origin
|
self.data = self.data
|
||||||
self:littleendian(2, 0)
|
.. string.char(0, 0) -- X-origin
|
||||||
self:littleendian(2, 0)
|
.. string.char(0, 0) -- Y-origin
|
||||||
-- width and height
|
.. string.char(self.width % 256, math.floor(self.width / 256)) -- width
|
||||||
self:littleendian(2, self.width)
|
.. string.char(self.height % 256, math.floor(self.height / 256)) -- height
|
||||||
self:littleendian(2, self.height)
|
.. string.char(24) -- pixel depth (RGB = 3 bytes = 24 bits)
|
||||||
-- pixel depth
|
.. string.char(0) -- image descriptor
|
||||||
self:insert(24)
|
|
||||||
-- image descriptor
|
|
||||||
self:insert(0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:encode_header()
|
function image:encode_header()
|
||||||
-- id length
|
self.data = self.data
|
||||||
self:insert(0) -- no image id info
|
.. string.char(0) -- image id
|
||||||
-- color map type
|
.. string.char(0) -- color map type
|
||||||
self:insert(0) -- no color map
|
.. string.char(2) -- image type (uncompressed true-color image = 2)
|
||||||
-- image type
|
self:encode_colormap_spec() -- color map specification
|
||||||
self:insert(2) -- uncompressed true-color image
|
self:encode_image_spec() -- image specification
|
||||||
-- color map specification
|
|
||||||
self:encode_colormap_spec()
|
|
||||||
-- image specification
|
|
||||||
self:encode_image_spec()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:encode_data()
|
function image:encode_data()
|
||||||
for _, row in ipairs(self.pixels) do
|
for _, row in ipairs(self.pixels) do
|
||||||
for _, pixel in ipairs(row) do
|
for _, pixel in ipairs(row) do
|
||||||
self:insert(pixel[3])
|
self.data = self.data
|
||||||
self:insert(pixel[2])
|
.. string.char(pixel[3], pixel[2], pixel[1])
|
||||||
self:insert(pixel[1])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function image:encode_footer()
|
||||||
|
self.data = self.data
|
||||||
|
.. string.char(0, 0, 0, 0) -- extension area offset
|
||||||
|
.. string.char(0, 0, 0, 0) -- developer area offset
|
||||||
|
.. "TRUEVISION-XFILE"
|
||||||
|
.. "."
|
||||||
|
.. string.char(0)
|
||||||
|
end
|
||||||
|
|
||||||
function image:encode()
|
function image:encode()
|
||||||
-- encode header
|
self:encode_header() -- header
|
||||||
self:encode_header()
|
|
||||||
-- no color map and image id data
|
-- no color map and image id data
|
||||||
-- encode data
|
self:encode_data() -- encode data
|
||||||
self:encode_data()
|
-- no extension or developer area
|
||||||
-- no extension area
|
self:encode_footer() -- footer
|
||||||
end
|
|
||||||
|
|
||||||
function image:get_data()
|
|
||||||
local data = ""
|
|
||||||
for _, bytes in ipairs(self.chunks) do
|
|
||||||
data = data .. string.char(unpack(bytes))
|
|
||||||
end
|
|
||||||
return data .. string.char(0, 0, 0, 0) .. string.char(0, 0, 0, 0) .. "TRUEVISION-XFILE." .. string.char(0)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:save(filename)
|
function image:save(filename)
|
||||||
self.data = self.data or self:get_data()
|
|
||||||
local f = assert(io.open(filename, "w"))
|
local f = assert(io.open(filename, "w"))
|
||||||
f:write(self.data)
|
f:write(self.data)
|
||||||
f:close()
|
f:close()
|
||||||
|
|
Loading…
Reference in New Issue