Add features table, refactor test texture generation, encode alpha for A1R5G5B5 images #1
91
init.lua
91
init.lua
|
@ -1,5 +1,23 @@
|
||||||
tga_encoder = {}
|
tga_encoder = {}
|
||||||
|
|
||||||
|
tga_encoder.features = {}
|
||||||
|
tga_encoder.features.color_format = {
|
||||||
|
["A1R5G5B5"] = true,
|
||||||
|
["B8G8R8"] = true,
|
||||||
|
["B8G8R8A8"] = true,
|
||||||
|
["Y8"] = true,
|
||||||
|
}
|
||||||
|
tga_encoder.features.colormap = {
|
||||||
|
}
|
||||||
|
tga_encoder.features.compression = {
|
||||||
|
["RAW"] = true,
|
||||||
|
["RLE"] = true,
|
||||||
|
}
|
||||||
|
tga_encoder.features.scanline_order = {
|
||||||
|
["bottom_top"] = true,
|
||||||
|
["top_bottom"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
local image = setmetatable({}, {
|
local image = setmetatable({}, {
|
||||||
__call = function(self, ...)
|
__call = function(self, ...)
|
||||||
local t = setmetatable({}, {__index = self})
|
local t = setmetatable({}, {__index = self})
|
||||||
|
@ -58,8 +76,8 @@ function image:encode_image_spec(properties)
|
||||||
)
|
)
|
||||||
local scanline_order = properties.scanline_order
|
local scanline_order = properties.scanline_order
|
||||||
assert (
|
assert (
|
||||||
"bottom-top" == scanline_order or
|
"bottom_top" == scanline_order or
|
||||||
"top-bottom" == scanline_order
|
"top_bottom" == scanline_order
|
||||||
)
|
)
|
||||||
local pixel_depth
|
local pixel_depth
|
||||||
if 0 ~= #properties.colormap then
|
if 0 ~= #properties.colormap then
|
||||||
|
@ -73,16 +91,21 @@ function image:encode_image_spec(properties)
|
||||||
local x_origin_hi = 0
|
local x_origin_hi = 0
|
||||||
local y_origin_lo = 0
|
local y_origin_lo = 0
|
||||||
local y_origin_hi = 0
|
local y_origin_hi = 0
|
||||||
local image_descriptor = 0 -- equal to bottom-top scanline order
|
local image_descriptor = 0 -- equal to bottom_top scanline order
|
||||||
local width_lo = self.width % 256
|
local width_lo = self.width % 256
|
||||||
local width_hi = math.floor(self.width / 256)
|
local width_hi = math.floor(self.width / 256)
|
||||||
local height_lo = self.height % 256
|
local height_lo = self.height % 256
|
||||||
local height_hi = math.floor(self.height / 256)
|
local height_hi = math.floor(self.height / 256)
|
||||||
if "top-bottom" == scanline_order then
|
if "top_bottom" == scanline_order then
|
||||||
image_descriptor = 32
|
image_descriptor = 32
|
||||||
y_origin_lo = height_lo
|
y_origin_lo = height_lo
|
||||||
y_origin_hi = height_hi
|
y_origin_hi = height_hi
|
||||||
end
|
end
|
||||||
|
if "A1R5G5B5" == color_format then
|
||||||
|
image_descriptor = image_descriptor + 1 -- 1 bit alpha channel
|
||||||
|
elseif "B8G8R8A8" == color_format then
|
||||||
|
image_descriptor = image_descriptor + 8 -- 8 bit alpha channel
|
||||||
|
end
|
||||||
self.data = self.data .. string.char (
|
self.data = self.data .. string.char (
|
||||||
x_origin_lo, x_origin_hi,
|
x_origin_lo, x_origin_hi,
|
||||||
y_origin_lo, y_origin_hi,
|
y_origin_lo, y_origin_hi,
|
||||||
|
@ -112,7 +135,8 @@ function image:encode_colormap(properties)
|
||||||
local max_sample_out = math.pow(2, 5) - 1
|
local max_sample_out = math.pow(2, 5) - 1
|
||||||
for i = 1,#colormap,1 do
|
for i = 1,#colormap,1 do
|
||||||
local color = colormap[i]
|
local color = colormap[i]
|
||||||
local colorword = 32768 +
|
local colorword = 0 +
|
||||||
|
((math.floor((color[4] / max_sample_in) + 0.5)) * 32768) + -- transparent if alpha < 128
|
||||||
((math.floor((color[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
((math.floor((color[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
||||||
((math.floor((color[2] * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
((math.floor((color[2] * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
||||||
((math.floor((color[3] * max_sample_out / max_sample_in) + 0.5)) * 1)
|
((math.floor((color[3] * max_sample_out / max_sample_in) + 0.5)) * 1)
|
||||||
|
@ -207,9 +231,17 @@ function image:encode_data(properties)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if "RAW" == compression then
|
if "RAW" == compression then
|
||||||
|
if 24 == self.pixel_depth then
|
||||||
self:encode_data_R8G8B8_as_A1R5G5B5_raw()
|
self:encode_data_R8G8B8_as_A1R5G5B5_raw()
|
||||||
|
elseif 32 == self.pixel_depth then
|
||||||
|
self:encode_data_R8G8B8A8_as_A1R5G5B5_raw()
|
||||||
|
end
|
||||||
elseif "RLE" == compression then
|
elseif "RLE" == compression then
|
||||||
|
if 24 == self.pixel_depth then
|
||||||
self:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
self:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
||||||
|
elseif 32 == self.pixel_depth then
|
||||||
|
self:encode_data_R8G8B8A8_as_A1R5G5B5_rle()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif "B8G8R8" == color_format then
|
elseif "B8G8R8" == color_format then
|
||||||
|
@ -284,6 +316,23 @@ end
|
||||||
|
|
||||||
function image:encode_data_R8G8B8_as_A1R5G5B5_raw()
|
function image:encode_data_R8G8B8_as_A1R5G5B5_raw()
|
||||||
assert(24 == self.pixel_depth)
|
assert(24 == self.pixel_depth)
|
||||||
|
for _, row in ipairs(self.pixels) do
|
||||||
|
for _, pixel in ipairs(row) do
|
||||||
|
pixel[4] = 255
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.pixel_depth = 32
|
||||||
|
self:encode_data_R8G8B8A8_as_A1R5G5B5_raw()
|
||||||
|
for _, row in ipairs(self.pixels) do
|
||||||
|
for _, pixel in ipairs(row) do
|
||||||
|
pixel[4] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.pixel_depth = 24
|
||||||
|
end
|
||||||
|
|
||||||
|
function image:encode_data_R8G8B8A8_as_A1R5G5B5_raw()
|
||||||
|
assert(32 == self.pixel_depth)
|
||||||
local raw_pixels = {}
|
local raw_pixels = {}
|
||||||
-- Sample depth rescaling is done according to the algorithm presented in:
|
-- Sample depth rescaling is done according to the algorithm presented in:
|
||||||
-- <https://www.w3.org/TR/2003/REC-PNG-20031110/#13Sample-depth-rescaling>
|
-- <https://www.w3.org/TR/2003/REC-PNG-20031110/#13Sample-depth-rescaling>
|
||||||
|
@ -291,7 +340,8 @@ function image:encode_data_R8G8B8_as_A1R5G5B5_raw()
|
||||||
local max_sample_out = math.pow(2, 5) - 1
|
local max_sample_out = math.pow(2, 5) - 1
|
||||||
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
|
||||||
local colorword = 32768 +
|
local colorword = 0 +
|
||||||
|
((math.floor((pixel[4] / max_sample_in) + 0.5)) * 32768) + -- transparent if alpha < 128
|
||||||
((math.floor((pixel[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
((math.floor((pixel[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
||||||
((math.floor((pixel[2] * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
((math.floor((pixel[2] * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
||||||
((math.floor((pixel[3] * max_sample_out / max_sample_in) + 0.5)) * 1)
|
((math.floor((pixel[3] * max_sample_out / max_sample_in) + 0.5)) * 1)
|
||||||
|
@ -304,10 +354,28 @@ end
|
||||||
|
|
||||||
function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
||||||
assert(24 == self.pixel_depth)
|
assert(24 == self.pixel_depth)
|
||||||
|
for _, row in ipairs(self.pixels) do
|
||||||
|
for _, pixel in ipairs(row) do
|
||||||
|
pixel[4] = 255
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.pixel_depth = 32
|
||||||
|
self:encode_data_R8G8B8A8_as_A1R5G5B5_rle()
|
||||||
|
for _, row in ipairs(self.pixels) do
|
||||||
|
for _, pixel in ipairs(row) do
|
||||||
|
pixel[4] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.pixel_depth = 24
|
||||||
|
end
|
||||||
|
|
||||||
|
function image:encode_data_R8G8B8A8_as_A1R5G5B5_rle()
|
||||||
|
assert(32 == self.pixel_depth)
|
||||||
local colorword = nil
|
local colorword = nil
|
||||||
local previous_r = nil
|
local previous_r = nil
|
||||||
local previous_g = nil
|
local previous_g = nil
|
||||||
local previous_b = nil
|
local previous_b = nil
|
||||||
|
local previous_a = nil
|
||||||
local raw_pixel = ''
|
local raw_pixel = ''
|
||||||
local raw_pixels = {}
|
local raw_pixels = {}
|
||||||
local count = 1
|
local count = 1
|
||||||
|
@ -320,9 +388,10 @@ function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
||||||
local max_sample_out = math.pow(2, 5) - 1
|
local max_sample_out = math.pow(2, 5) - 1
|
||||||
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
|
||||||
if pixel[1] ~= previous_r or pixel[2] ~= previous_g or pixel[3] ~= previous_b or count == 128 then
|
if pixel[1] ~= previous_r or pixel[2] ~= previous_g or pixel[3] ~= previous_b or pixel[4] ~= previous_a or count == 128 then
|
||||||
if nil ~= previous_r then
|
if nil ~= previous_r then
|
||||||
colorword = 32768 +
|
colorword = 0 +
|
||||||
|
((math.floor((previous_a / max_sample_in) + 0.5)) * 32768) + -- transparent if alpha < 128
|
||||||
((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
||||||
((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
||||||
((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1)
|
((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1)
|
||||||
|
@ -357,12 +426,14 @@ function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
|
||||||
previous_r = pixel[1]
|
previous_r = pixel[1]
|
||||||
previous_g = pixel[2]
|
previous_g = pixel[2]
|
||||||
previous_b = pixel[3]
|
previous_b = pixel[3]
|
||||||
|
previous_a = pixel[4]
|
||||||
else
|
else
|
||||||
count = count + 1
|
count = count + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
colorword = 32768 +
|
colorword = 0 +
|
||||||
|
((math.floor((previous_a / max_sample_in) + 0.5)) * 32768) + -- transparent if alpha < 128
|
||||||
((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) +
|
||||||
((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) +
|
||||||
((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1)
|
((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1)
|
||||||
|
@ -585,7 +656,7 @@ function image:encode(properties)
|
||||||
local properties = properties or {}
|
local properties = properties or {}
|
||||||
properties.colormap = properties.colormap or {}
|
properties.colormap = properties.colormap or {}
|
||||||
properties.compression = properties.compression or "RAW"
|
properties.compression = properties.compression or "RAW"
|
||||||
properties.scanline_order = properties.scanline_order or "bottom-top"
|
properties.scanline_order = properties.scanline_order or "bottom_top"
|
||||||
|
|
||||||
self.pixel_depth = #self.pixels[1][1] * 8
|
self.pixel_depth = #self.pixels[1][1] * 8
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@ local _ = { 0 }
|
||||||
local R = { 1 }
|
local R = { 1 }
|
||||||
local G = { 2 }
|
local G = { 2 }
|
||||||
local B = { 3 }
|
local B = { 3 }
|
||||||
|
local W = { 4 }
|
||||||
|
|
||||||
local pixels_colormapped_bt = {
|
local pixels_colormapped_bt = {
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
|
@ -24,59 +25,85 @@ local pixels_colormapped_tb = {
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
}
|
}
|
||||||
|
|
||||||
image_colormapped_bt = tga_encoder.image(pixels_colormapped_bt)
|
local pixels_colormapped_by_scanline_order = {
|
||||||
image_colormapped_tb = tga_encoder.image(pixels_colormapped_tb)
|
["bottom_top"] = pixels_colormapped_bt,
|
||||||
|
["top_bottom"] = pixels_colormapped_tb,
|
||||||
|
}
|
||||||
|
|
||||||
colormap_32bpp = {
|
local colormap_32bpp = {
|
||||||
{ 0, 0, 0, 128 },
|
{ 0, 0, 0, 127 },
|
||||||
{ 255, 0, 0, 255 },
|
{ 255, 0, 0, 255 },
|
||||||
{ 0, 255, 0, 255 },
|
{ 0, 255, 0, 255 },
|
||||||
{ 0, 0, 255, 255 },
|
{ 0, 0, 255, 255 },
|
||||||
|
{ 255, 255, 255, 128 },
|
||||||
}
|
}
|
||||||
image_colormapped_bt:save(
|
|
||||||
"type1_32bpp_bt.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "B8G8R8A8", scanline_order = "bottom-top" }
|
|
||||||
)
|
|
||||||
image_colormapped_tb:save(
|
|
||||||
"type1_32bpp_tb.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "B8G8R8A8", scanline_order = "top-bottom" }
|
|
||||||
)
|
|
||||||
image_colormapped_bt:save(
|
|
||||||
"type1_16bpp_bt.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "A1R5G5B5", scanline_order = "bottom-top" }
|
|
||||||
)
|
|
||||||
image_colormapped_tb:save(
|
|
||||||
"type1_16bpp_tb.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "A1R5G5B5", scanline_order = "top-bottom" }
|
|
||||||
)
|
|
||||||
|
|
||||||
colormap_24bpp = {
|
local colormap_24bpp = {
|
||||||
{ 0, 0, 0 },
|
{ 0, 0, 0 },
|
||||||
{ 255, 0, 0 },
|
{ 255, 0, 0 },
|
||||||
{ 0, 255, 0 },
|
{ 0, 255, 0 },
|
||||||
{ 0, 0, 255 },
|
{ 0, 0, 255 },
|
||||||
|
{ 255, 255, 255 },
|
||||||
}
|
}
|
||||||
image_colormapped_bt:save(
|
|
||||||
"type1_24bpp_bt.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "B8G8R8", scanline_order = "bottom-top" }
|
|
||||||
)
|
|
||||||
image_colormapped_tb:save(
|
|
||||||
"type1_24bpp_tb.tga",
|
|
||||||
{ colormap = colormap_32bpp, color_format = "B8G8R8", scanline_order = "top-bottom" }
|
|
||||||
)
|
|
||||||
|
|
||||||
local _ = { 0, 0, 0, 128 }
|
local colormap_16bpp = {
|
||||||
|
{ 0, 0, 0, 0 },
|
||||||
|
{ 255, 0, 0, 255 },
|
||||||
|
{ 0, 255, 0, 255 },
|
||||||
|
{ 0, 0, 255, 255 },
|
||||||
|
{ 255, 255, 255, 255 },
|
||||||
|
}
|
||||||
|
|
||||||
|
local colormap_by_color_format = {
|
||||||
|
["A1R5G5B5"] = colormap_16bpp,
|
||||||
|
["B8G8R8"] = colormap_24bpp,
|
||||||
|
["B8G8R8A8"] = colormap_32bpp,
|
||||||
|
}
|
||||||
|
|
||||||
|
for color_format, _ in pairs(
|
||||||
|
tga_encoder.features.color_format
|
||||||
|
) do
|
||||||
|
if ("Y8" ~= color_format) then
|
||||||
|
for scanline_order, _ in pairs(
|
||||||
|
tga_encoder.features.scanline_order
|
||||||
|
) do
|
||||||
|
local filename
|
||||||
|
local pixels
|
||||||
|
filename = "type1" ..
|
||||||
|
'-' .. color_format ..
|
||||||
|
'-' .. scanline_order ..
|
||||||
|
'.tga'
|
||||||
|
pixels = pixels_colormapped_by_scanline_order[
|
||||||
|
scanline_order
|
||||||
|
]
|
||||||
|
local colormap = colormap_by_color_format[
|
||||||
|
color_format
|
||||||
|
]
|
||||||
|
local properties = {
|
||||||
|
colormap = colormap,
|
||||||
|
color_format = color_format,
|
||||||
|
scanline_order = scanline_order,
|
||||||
|
}
|
||||||
|
print(filename)
|
||||||
|
local image = tga_encoder.image(pixels)
|
||||||
|
image:save(filename, properties)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local _ = { 0, 0, 0, 127 }
|
||||||
local R = { 255, 0, 0, 255 }
|
local R = { 255, 0, 0, 255 }
|
||||||
local G = { 0, 255, 0, 255 }
|
local G = { 0, 255, 0, 255 }
|
||||||
local B = { 0, 0, 255, 255 }
|
local B = { 0, 0, 255, 255 }
|
||||||
|
local W = { 255, 255, 255, 128 }
|
||||||
|
|
||||||
local pixels_rgba_bt = {
|
local pixels_rgba_bt = {
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
|
@ -92,38 +119,24 @@ local pixels_rgba_tb = {
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
}
|
}
|
||||||
|
|
||||||
image_rgba_bt = tga_encoder.image(pixels_rgba_bt)
|
local pixels_rgba_by_scanline_order = {
|
||||||
image_rgba_tb = tga_encoder.image(pixels_rgba_tb)
|
["bottom_top"] = pixels_rgba_bt,
|
||||||
|
["top_bottom"] = pixels_rgba_tb,
|
||||||
image_rgba_bt:save(
|
}
|
||||||
"type2_32bpp_bt.tga",
|
|
||||||
{ color_format="B8G8R8A8", compression="RAW", scanline_order = "bottom-top" }
|
|
||||||
)
|
|
||||||
image_rgba_tb:save(
|
|
||||||
"type2_32bpp_tb.tga",
|
|
||||||
{ color_format="B8G8R8A8", compression="RAW", scanline_order = "top-bottom" }
|
|
||||||
)
|
|
||||||
image_rgba_bt:save(
|
|
||||||
"type10_32bpp_bt.tga",
|
|
||||||
{ color_format="B8G8R8A8", compression="RLE", scanline_order = "bottom-top" }
|
|
||||||
)
|
|
||||||
image_rgba_tb:save(
|
|
||||||
"type10_32bpp_tb.tga",
|
|
||||||
{ color_format="B8G8R8A8", compression="RLE", scanline_order = "top-bottom" }
|
|
||||||
)
|
|
||||||
|
|
||||||
local _ = { 0, 0, 0 }
|
local _ = { 0, 0, 0 }
|
||||||
local R = { 255, 0, 0 }
|
local R = { 255, 0, 0 }
|
||||||
local G = { 0, 255, 0 }
|
local G = { 0, 255, 0 }
|
||||||
local B = { 0, 0, 255 }
|
local B = { 0, 0, 255 }
|
||||||
|
local W = { 255, 255, 255 }
|
||||||
|
|
||||||
local pixels_rgb_bt = {
|
local pixels_rgb_bt = {
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
|
@ -139,42 +152,71 @@ local pixels_rgb_tb = {
|
||||||
{ _, R, G, _, _, _, _, _, },
|
{ _, R, G, _, _, _, _, _, },
|
||||||
{ _, _, G, _, G, B, B, B, },
|
{ _, _, G, _, G, B, B, B, },
|
||||||
{ _, _, G, G, G, B, _, B, },
|
{ _, _, G, G, G, B, _, B, },
|
||||||
{ _, _, _, _, _, B, B, B, },
|
{ W, W, _, _, _, B, B, B, },
|
||||||
{ _, _, _, _, _, B, _, B, },
|
{ W, W, _, _, _, B, _, B, },
|
||||||
}
|
}
|
||||||
|
|
||||||
image_rgb_bt = tga_encoder.image(pixels_rgb_bt)
|
local pixels_rgb_by_scanline_order = {
|
||||||
image_rgb_tb = tga_encoder.image(pixels_rgb_tb)
|
["bottom_top"] = pixels_rgb_bt,
|
||||||
|
["top_bottom"] = pixels_rgb_tb,
|
||||||
|
}
|
||||||
|
|
||||||
image_rgb_bt:save(
|
local tga_type_by_compression = {
|
||||||
"type2_24bpp_bt.tga",
|
["RAW"] = "2",
|
||||||
{ color_format="B8G8R8", compression="RAW", scanline_order = "bottom-top" }
|
["RLE"] = "10",
|
||||||
)
|
}
|
||||||
image_rgb_tb:save(
|
|
||||||
"type2_24bpp_tb.tga",
|
local pixels_by_scanline_order_by_color_format = {
|
||||||
{ color_format="B8G8R8", compression="RAW", scanline_order = "top-bottom" }
|
["A1R5G5B5"] = pixels_rgba_by_scanline_order,
|
||||||
)
|
["B8G8R8"] = pixels_rgb_by_scanline_order,
|
||||||
image_rgb_bt:save(
|
["B8G8R8A8"] = pixels_rgba_by_scanline_order,
|
||||||
"type10_24bpp_bt.tga",
|
["Y8"] = pixels_rgb_by_scanline_order,
|
||||||
{ color_format="B8G8R8", compression="RLE", scanline_order = "bottom-top" }
|
}
|
||||||
)
|
|
||||||
image_rgb_tb:save(
|
for color_format, _ in pairs(
|
||||||
"type10_24bpp_tb.tga",
|
tga_encoder.features.color_format
|
||||||
{ color_format="B8G8R8", compression="RLE", scanline_order = "top-bottom" }
|
) do
|
||||||
)
|
local pixels_by_scanline_order = pixels_by_scanline_order_by_color_format[
|
||||||
image_rgb_bt:save(
|
color_format
|
||||||
"type2_16bpp_bt.tga",
|
]
|
||||||
{ color_format="A1R5G5B5", compression="RAW", scanline_order = "bottom-top" }
|
for compression, _ in pairs(
|
||||||
)
|
tga_encoder.features.compression
|
||||||
image_rgb_tb:save(
|
) do
|
||||||
"type2_16bpp_tb.tga",
|
local tga_type
|
||||||
{ color_format="A1R5G5B5", compression="RAW", scanline_order = "top-bottom" }
|
if (
|
||||||
)
|
"Y8" == color_format and
|
||||||
image_rgb_bt:save(
|
"RAW" == compression
|
||||||
"type10_16bpp_bt.tga",
|
) then
|
||||||
{ color_format="A1R5G5B5", compression="RLE", scanline_order = "bottom-top" }
|
tga_type = "3"
|
||||||
)
|
else
|
||||||
image_rgb_tb:save(
|
tga_type = tga_type_by_compression[
|
||||||
"type10_16bpp_tb.tga",
|
compression
|
||||||
{ color_format="A1R5G5B5", compression="RLE", scanline_order = "top-bottom" }
|
]
|
||||||
)
|
end
|
||||||
|
-- tga_encoder can not encode grayscale RLE (type 11)
|
||||||
|
if not(
|
||||||
|
"Y8" == color_format and
|
||||||
|
"RLE" == compression
|
||||||
|
) then
|
||||||
|
for scanline_order, _ in pairs(
|
||||||
|
tga_encoder.features.scanline_order
|
||||||
|
) do
|
||||||
|
local filename = "type" .. tga_type ..
|
||||||
|
'-' .. color_format ..
|
||||||
|
'-' .. scanline_order ..
|
||||||
|
'.tga'
|
||||||
|
local pixels = pixels_by_scanline_order[
|
||||||
|
scanline_order
|
||||||
|
]
|
||||||
|
local properties = {
|
||||||
|
color_format = color_format,
|
||||||
|
compression = compression,
|
||||||
|
scanline_order = scanline_order,
|
||||||
|
}
|
||||||
|
print(filename)
|
||||||
|
local image = tga_encoder.image(pixels)
|
||||||
|
image:save(filename, properties)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue