diff --git a/init.lua b/init.lua index dbf1d1d..18699f4 100644 --- a/init.lua +++ b/init.lua @@ -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: + -- + 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