Encode alpha channel for uncompressed A1R5G5B5 images

This commit is contained in:
Nils Dagsson Moskopp 2023-10-18 01:23:08 +02:00
parent fa28f4c8de
commit 2e0471c81f
Signed by: erle
GPG Key ID: A3BC671C35191080
1 changed files with 26 additions and 1 deletions

View File

@ -225,7 +225,11 @@ function image:encode_data(properties)
end
else
if "RAW" == compression then
self:encode_data_R8G8B8_as_A1R5G5B5_raw()
if 24 == self.pixel_depth then
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
self:encode_data_R8G8B8_as_A1R5G5B5_rle()
end
@ -320,6 +324,27 @@ function image:encode_data_R8G8B8_as_A1R5G5B5_raw()
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_R8G8B8A8_as_A1R5G5B5_raw()
assert(32 == self.pixel_depth)
local raw_pixels = {}
-- Sample depth rescaling is done according to the algorithm presented in:
-- <https://www.w3.org/TR/2003/REC-PNG-20031110/#13Sample-depth-rescaling>
local max_sample_in = math.pow(2, 8) - 1
local max_sample_out = math.pow(2, 5) - 1
for _, row in ipairs(self.pixels) do
for _, pixel in ipairs(row) do
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[2] * max_sample_out / max_sample_in) + 0.5)) * 32) +
((math.floor((pixel[3] * max_sample_out / max_sample_in) + 0.5)) * 1)
local raw_pixel = string.char(colorword % 256, math.floor(colorword / 256))
raw_pixels[#raw_pixels + 1] = raw_pixel
end
end
self.data = self.data .. table.concat(raw_pixels)
end
function image:encode_data_R8G8B8_as_A1R5G5B5_rle()
assert(24 == self.pixel_depth)
local colorword = nil