3 local image = setmetatable({}, {
4 __call = function(self, ...)
5 local t = setmetatable({}, {__index = self})
11 function image:constructor(pixels)
14 self.width = #pixels[1]
20 function image:encode_colormap_spec()
22 .. string.char(0, 0) -- first entry index
23 .. string.char(0, 0) -- number of entries
24 .. string.char(0) -- bits per pixel
27 function image:encode_image_spec()
29 .. string.char(0, 0) -- X-origin
30 .. string.char(0, 0) -- Y-origin
31 .. string.char(self.width % 256, math.floor(self.width / 256)) -- width
32 .. string.char(self.height % 256, math.floor(self.height / 256)) -- height
33 .. string.char(24) -- pixel depth (RGB = 3 bytes = 24 bits)
34 .. string.char(0) -- image descriptor
37 function image:encode_header()
39 .. string.char(0) -- image id
40 .. string.char(0) -- color map type
41 .. string.char(2) -- image type (uncompressed true-color image = 2)
42 self:encode_colormap_spec() -- color map specification
43 self:encode_image_spec() -- image specification
46 function image:encode_data()
47 for _, row in ipairs(self.pixels) do
48 for _, pixel in ipairs(row) do
50 .. string.char(pixel[3], pixel[2], pixel[1])
55 function image:encode_footer()
57 .. string.char(0, 0, 0, 0) -- extension area offset
58 .. string.char(0, 0, 0, 0) -- developer area offset
64 function image:encode()
65 self:encode_header() -- header
66 -- no color map and image id data
67 self:encode_data() -- encode data
68 -- no extension or developer area
69 self:encode_footer() -- footer
72 function image:save(filename)
73 local f = assert(io.open(filename, "w"))
78 tga_encoder.image = image