]> git.lizzy.rs Git - tga_encoder.git/blob - init.lua
45b9e85a238701cbf5f5f4cc5cb42826fcbdba28
[tga_encoder.git] / init.lua
1 tga_encoder = {}
2
3 local LUA_ARGS_LIMIT = 1000
4
5 local image = setmetatable({}, {
6         __call = function(self, ...)
7                 local t = setmetatable({}, {__index = self})
8                 t:constructor(...)
9                 return t
10         end,
11 })
12
13 function image:constructor(pixels)
14         self.bytes = {}
15         self.chunks = {self.bytes}
16         self.pixels = pixels
17         self.width = #pixels[1]
18         self.height = #pixels
19
20         self:encode()
21 end
22
23 function image:insert(byte)
24         table.insert(self.bytes, byte)
25         if #self.bytes == LUA_ARGS_LIMIT then
26                 self.bytes = {}
27                 table.insert(self.chunks, self.bytes)
28         end
29 end
30
31 function image:littleendian(size, value)
32         for i = 1, size do
33                 local byte = value % 256
34                 value = value - byte
35                 value = value / 256
36                 self:insert(byte)
37         end
38 end
39
40 function image:encode_colormap_spec()
41         -- first entry index
42         self:littleendian(2, 0)
43         -- number of entries
44         self:littleendian(2, 0)
45         -- number of bits per pixel
46         self:insert(0)
47 end
48
49 function image:encode_image_spec()
50         -- X- and Y- origin
51         self:littleendian(2, 0)
52         self:littleendian(2, 0)
53         -- width and height
54         self:littleendian(2, self.width)
55         self:littleendian(2, self.height)
56         -- pixel depth
57         self:insert(24)
58         -- image descriptor
59         self:insert(0)
60 end
61
62 function image:encode_header()
63         -- id length
64         self:insert(0) -- no image id info
65         -- color map type
66         self:insert(0) -- no color map
67         -- image type
68         self:insert(2) -- uncompressed true-color image
69         -- color map specification
70         self:encode_colormap_spec()
71         -- image specification
72         self:encode_image_spec()
73 end
74
75 function image:encode_data()
76         for _, row in ipairs(self.pixels) do
77                 for _, pixel in ipairs(row) do
78                         self:insert(pixel[3])
79                         self:insert(pixel[2])
80                         self:insert(pixel[1])
81                 end
82         end
83 end
84
85 function image:encode()
86         -- encode header
87         self:encode_header()
88         -- no color map and image id data
89         -- encode data
90         self:encode_data()
91         -- no extension area
92 end
93
94 function image:get_data()
95         local data = ""
96         for _, bytes in ipairs(self.chunks) do
97                 data = data .. string.char(unpack(bytes))
98         end
99         return data .. string.char(0, 0, 0, 0) .. string.char(0, 0, 0, 0) .. "TRUEVISION-XFILE." .. string.char(0)
100 end
101
102 function image:save(filename)
103         self.data = self.data or self:get_data()
104         local f = assert(io.open(filename, "w"))
105         f:write(self.data)
106         f:close()
107 end
108
109 tga_encoder.image = image