Allow to specify color format

This commit is contained in:
Nils Dagsson Moskopp 2022-05-16 02:48:51 +02:00
parent fa23775bf9
commit 7b94fc026d
No known key found for this signature in database
GPG Key ID: A3BC671C35191080
2 changed files with 60 additions and 45 deletions

@ -39,7 +39,7 @@ for x = 1,6,1 do -- left to right
pixels[z][x] = color
end
end
tga_encoder.image(pixels):save("gradient_8bpp_raw.tga", {colors="BW", compression="RAW", pixel_depth=8})
tga_encoder.image(pixels):save("gradient_8bpp_raw.tga", {color_format="Y8", compression="RAW"})
local pixels = {}
for x = 1,16,1 do -- left to right
@ -59,11 +59,11 @@ for x = 1,16,1 do -- left to right
end
end
local gradients = tga_encoder.image(pixels)
gradients:save("gradients_8bpp_raw.tga", {colors="BW", compression="RAW", pixel_depth=8})
gradients:save("gradients_16bpp_raw.tga", {colors="RGB", compression="RAW", pixel_depth=16})
gradients:save("gradients_16bpp_rle.tga", {colors="RGB", compression="RLE", pixel_depth=16})
gradients:save("gradients_24bpp_raw.tga", {colors="RGB", compression="RAW", pixel_depth=24})
gradients:save("gradients_24bpp_rle.tga", {colors="RGB", compression="RLE", pixel_depth=24})
gradients:save("gradients_8bpp_raw.tga", {color_format="Y8", compression="RAW"})
gradients:save("gradients_16bpp_raw.tga", {color_format="A1R5G5B5", compression="RAW"})
gradients:save("gradients_16bpp_rle.tga", {color_format="A1R5G5B5", compression="RLE"})
gradients:save("gradients_24bpp_raw.tga", {color_format="B8G8R8", compression="RAW"})
gradients:save("gradients_24bpp_rle.tga", {color_format="B8G8R8", compression="RLE"})
for x = 1,16,1 do -- left to right
for z = 1,16,1 do -- bottom to top
@ -72,7 +72,7 @@ for x = 1,16,1 do -- left to right
pixels[z][x] = color
end
end
gradients:save("gradients_32bpp_raw.tga", {colors="RGBA", compression="RAW", pixel_depth=32})
gradients:save("gradients_32bpp_raw.tga", {color_format="B8G8R8A8", compression="RAW"})
local pixels = {}
for x = 1,512,1 do -- left to right
@ -94,6 +94,6 @@ for x = 1,512,1 do -- left to right
pixels[z][x] = color
end
end
tga_encoder.image(pixels):save("fractal_8bpp.tga", {colors="BW", pixel_depth=8})
tga_encoder.image(pixels):save("fractal_16bpp.tga", {colors="RGB", pixel_depth=16})
tga_encoder.image(pixels):save("fractal_24bpp.tga", {colors="RGB", pixel_depth=24})
tga_encoder.image(pixels):save("fractal_8bpp.tga", {color_format="Y8"})
tga_encoder.image(pixels):save("fractal_16bpp.tga", {color_format="A1R5G5B5"})
tga_encoder.image(pixels):save("fractal_24bpp.tga", {color_format="B8G8R8"})

@ -22,14 +22,21 @@ function image:encode_colormap_spec()
end
function image:encode_image_spec(properties)
local colors = properties.colors
local pixel_depth = properties.pixel_depth
local color_format = properties.color_format
assert(
"BW" == colors and 8 == pixel_depth or -- (8 bit grayscale = 1 byte = 8 bits)
"RGB" == colors and 16 == pixel_depth or -- (A1R5G5B5 = 2 bytes = 16 bits)
"RGB" == colors and 24 == pixel_depth or -- (B8G8R8 = 3 bytes = 24 bits)
"RGBA" == colors and 32 == pixel_depth -- (B8G8R8A8 = 4 bytes = 32 bits)
"Y8" == color_format or -- (8 bit grayscale = 1 byte = 8 bits)
"A1R5G5B5" == color_format or -- (A1R5G5B5 = 2 bytes = 16 bits)
"B8G8R8" == color_format or -- (B8G8R8 = 3 bytes = 24 bits)
"B8G8R8A8" == color_format -- (B8G8R8A8 = 4 bytes = 32 bits)
)
pixel_depth_by_color_format = {
["Y8"] = 8,
["A1R5G5B5"] = 16,
["B8G8R8"] = 24,
["B8G8R8A8"] = 32,
}
local pixel_depth = pixel_depth_by_color_format[color_format]
assert( nil ~= pixel_depth)
self.data = self.data
.. string.char(0, 0) -- X-origin
.. string.char(0, 0) -- Y-origin
@ -40,16 +47,15 @@ function image:encode_image_spec(properties)
end
function image:encode_header(properties)
local colors = properties.colors
local color_format = properties.color_format
local compression = properties.compression
local pixel_depth = properties.pixel_depth
local image_type
if "BW" == colors and "RAW" == compression and 8 == pixel_depth then
if "Y8" == color_format and "RAW" == compression then
image_type = 3 -- grayscale
elseif (
"RGB" == colors and 16 == pixel_depth or
"RGB" == colors and 24 == pixel_depth or
"RGBA" == colors and 32 == pixel_depth
"A1R5G5B5" == color_format or
"B8G8R8" == color_format or
"B8G8R8A8" == color_format
) then
if "RAW" == compression then
image_type = 2 -- RAW RGB(A)
@ -57,6 +63,7 @@ function image:encode_header(properties)
image_type = 10 -- RLE RGB
end
end
assert( nil ~= image_type )
self.data = self.data
.. string.char(0) -- image id
.. string.char(0) -- color map type
@ -66,37 +73,35 @@ function image:encode_header(properties)
end
function image:encode_data(properties)
local colors = properties.colors
local color_format = properties.color_format
local compression = properties.compression
local pixel_depth = properties.pixel_depth
self.pixel_depth = #self.pixels[1][1] * 8
if "BW" == colors and "RAW" == compression and 8 == pixel_depth then
if "Y8" == color_format and "RAW" == compression then
if 8 == self.pixel_depth then
self:encode_data_bw8_to_bw8_raw()
self:encode_data_Y8_as_Y8_raw()
elseif 24 == self.pixel_depth then
self:encode_data_r8g8b8_to_bw8_raw()
self:encode_data_R8G8B8_as_Y8_raw()
end
elseif "RGB" == colors and 16 == pixel_depth then
elseif "A1R5G5B5" == color_format then
if "RAW" == compression then
self:encode_data_a1r5g5b5_raw()
self:encode_data_R8G8B8_as_A1R5G5B5_raw()
elseif "RLE" == compression then
self:encode_data_a1r5g5b5_rle()
self:encode_data_R8G8B8_as_A1R5G5B5_rle()
end
elseif "RGB" == colors and 24 == pixel_depth then
elseif "B8G8R8" == color_format then
if "RAW" == compression then
self:encode_data_r8g8b8_raw()
self:encode_data_R8G8B8_as_B8G8R8_raw()
elseif "RLE" == compression then
self:encode_data_r8g8b8_rle()
self:encode_data_R8G8B8_as_B8G8R8_rle()
end
elseif "RGBA" == colors and 32 == pixel_depth then
elseif "B8G8R8A8" == color_format then
if "RAW" == compression then
self:encode_data_r8g8b8a8_raw()
self:encode_data_R8G8B8A8_as_B8G8R8A8_raw()
end
end
end
function image:encode_data_bw8_to_bw8_raw()
function image:encode_data_Y8_as_Y8_raw()
assert(8 == self.pixel_depth)
local raw_pixels = {}
for _, row in ipairs(self.pixels) do
@ -108,7 +113,7 @@ function image:encode_data_bw8_to_bw8_raw()
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_r8g8b8_to_bw8_raw()
function image:encode_data_R8G8B8_as_Y8_raw()
assert(24 == self.pixel_depth)
local raw_pixels = {}
for _, row in ipairs(self.pixels) do
@ -130,7 +135,7 @@ function image:encode_data_r8g8b8_to_bw8_raw()
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_a1r5g5b5_raw()
function image:encode_data_R8G8B8_as_A1R5G5B5_raw()
assert(24 == self.pixel_depth)
local raw_pixels = {}
-- Sample depth rescaling is done according to the algorithm presented in:
@ -150,7 +155,7 @@ function image:encode_data_a1r5g5b5_raw()
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_a1r5g5b5_rle()
function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
assert(24 == self.pixel_depth)
local colorword = nil
local previous_r = nil
@ -240,7 +245,7 @@ function image:encode_data_a1r5g5b5_rle()
self.data = self.data .. table.concat(packets)
end
function image:encode_data_r8g8b8_raw()
function image:encode_data_R8G8B8_as_B8G8R8_raw()
assert(24 == self.pixel_depth)
local raw_pixels = {}
for _, row in ipairs(self.pixels) do
@ -252,7 +257,7 @@ function image:encode_data_r8g8b8_raw()
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_r8g8b8_rle()
function image:encode_data_R8G8B8_as_B8G8R8_rle()
assert(24 == self.pixel_depth)
local previous_r = nil
local previous_g = nil
@ -329,7 +334,7 @@ function image:encode_data_r8g8b8_rle()
self.data = self.data .. table.concat(packets)
end
function image:encode_data_r8g8b8a8_raw()
function image:encode_data_R8G8B8A8_as_B8G8R8A8_raw()
assert(32 == self.pixel_depth)
local raw_pixels = {}
for _, row in ipairs(self.pixels) do
@ -361,9 +366,19 @@ end
function image:save(filename, properties)
local properties = properties or {}
properties.colors = properties.colors or "RGB"
properties.compression = properties.compression or "RAW"
properties.pixel_depth = properties.pixel_depth or 24
self.pixel_depth = #self.pixels[1][1] * 8
if nil == properties.color_format then
if 8 == self.pixel_depth then
properties.color_format = "Y8"
elseif 24 == self.pixel_depth then
properties.color_format = "B8G8R8"
elseif 32 == self.pixel_depth then
properties.color_format = "B8G8R8A8"
end
end
assert( nil ~= properties.color_format )
self:encode(properties)