unicode_text/pixelops.lua

178 lines
4.8 KiB
Lua
Raw Permalink Normal View History

2023-03-17 03:39:41 +01:00
#!/usr/bin/env lua5.1
--[[
Copyright © 2023 Nils Dagsson Moskopp (erle)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Dieses Programm hat das Ziel, die Medienkompetenz der Leser zu
steigern. Gelegentlich packe ich sogar einen handfesten Buffer
Overflow oder eine Format String Vulnerability zwischen die anderen
Codezeilen und schreibe das auch nicht dran.
]]--
pixelops = {}
-- Use this to invert image scanline order!
pixelops.flip_vertically = function(pixels)
2023-03-17 03:39:41 +01:00
local result = {}
local height = #pixels
for h = 1, height do
local scanline = height - h + 1
result[scanline] = pixels[h]
end
return result
end
-- Test helper
local tc = table.concat
-- Test: pixelops.flip_vertically() with one-byte pixels
2023-03-17 03:39:41 +01:00
local i = {
{ { 1 }, { 2 }, { 3 } },
{ { 4 }, { 5 }, { 6 } },
{ { 7 }, { 8 }, { 9 } },
}
assert(
"123" == tc({i[1][1][1], i[1][2][1], i[1][3][1]}) and
"456" == tc({i[2][1][1], i[2][2][1], i[2][3][1]}) and
"789" == tc({i[3][1][1], i[3][2][1], i[3][3][1]})
)
local j = pixelops.flip_vertically(i)
2023-03-17 03:39:41 +01:00
assert(
"789" == tc({j[1][1][1], j[1][2][1], j[1][3][1]}) and
"456" == tc({j[2][1][1], j[2][2][1], j[2][3][1]}) and
"123" == tc({j[3][1][1], j[3][2][1], j[3][3][1]})
)
local k = pixelops.flip_vertically(j)
2023-03-17 03:39:41 +01:00
assert(
"123" == tc({k[1][1][1], k[1][2][1], k[1][3][1]}) and
"456" == tc({k[2][1][1], k[2][2][1], k[2][3][1]}) and
"789" == tc({k[3][1][1], k[3][2][1], k[3][3][1]})
)
i = nil
j = nil
k = nil
-- Test: pixelops.flip_vertically() with three-byte pixels
2023-03-17 03:39:41 +01:00
local i = {
{ { 1, 1, 0 }, { 2, 2, 0 }, { 3, 3, 0 } },
{ { 4, 4, 0 }, { 5, 5, 0 }, { 6, 6, 0 } },
{ { 7, 7, 0 }, { 8, 8, 0 }, { 9, 9, 0 } },
}
assert(
"110220330" == tc({tc(i[1][1]), tc(i[1][2]), tc(i[1][3])}) and
"440550660" == tc({tc(i[2][1]), tc(i[2][2]), tc(i[2][3])}) and
"770880990" == tc({tc(i[3][1]), tc(i[3][2]), tc(i[3][3])})
)
local j = pixelops.flip_vertically(i)
2023-03-17 03:39:41 +01:00
assert(
"770880990" == tc({tc(j[1][1]), tc(j[1][2]), tc(j[1][3])}) and
"440550660" == tc({tc(j[2][1]), tc(j[2][2]), tc(j[2][3])}) and
"110220330" == tc({tc(j[3][1]), tc(j[3][2]), tc(j[3][3])})
)
local k = pixelops.flip_vertically(j)
2023-03-17 03:39:41 +01:00
assert(
"110220330" == tc({tc(k[1][1]), tc(k[1][2]), tc(k[1][3])}) and
"440550660" == tc({tc(k[2][1]), tc(k[2][2]), tc(k[2][3])}) and
"770880990" == tc({tc(k[3][1]), tc(k[3][2]), tc(k[3][3])})
)
i = nil
j = nil
k = nil
-- Test: pixelops.flip_vertically() with four-byte pixels
2023-03-17 03:39:41 +01:00
local i = {
{ { 1, 1, 0, 0 }, { 2, 2, 0, 0 }, { 3, 3, 0, 0 } },
{ { 4, 4, 0, 0 }, { 5, 5, 0, 0 }, { 6, 6, 0, 0 } },
{ { 7, 7, 0, 0 }, { 8, 8, 0, 0 }, { 9, 9, 0, 0 } },
}
assert(
"110022003300" == tc({tc(i[1][1]), tc(i[1][2]), tc(i[1][3])}) and
"440055006600" == tc({tc(i[2][1]), tc(i[2][2]), tc(i[2][3])}) and
"770088009900" == tc({tc(i[3][1]), tc(i[3][2]), tc(i[3][3])})
)
local j = pixelops.flip_vertically(i)
2023-03-17 03:39:41 +01:00
assert(
"770088009900" == tc({tc(j[1][1]), tc(j[1][2]), tc(j[1][3])}) and
"440055006600" == tc({tc(j[2][1]), tc(j[2][2]), tc(j[2][3])}) and
"110022003300" == tc({tc(j[3][1]), tc(j[3][2]), tc(j[3][3])})
)
local k = pixelops.flip_vertically(j)
2023-03-17 03:39:41 +01:00
assert(
"110022003300" == tc({tc(k[1][1]), tc(k[1][2]), tc(k[1][3])}) and
"440055006600" == tc({tc(k[2][1]), tc(k[2][2]), tc(k[2][3])}) and
"770088009900" == tc({tc(k[3][1]), tc(k[3][2]), tc(k[3][3])})
)
i = nil
j = nil
k = nil
pixelops.pad_right = function(pixels, amount, padding)
2023-03-17 03:39:41 +01:00
assert(
"table" == type(pixels)
)
assert(
"number" == type(amount) and
amount > 0
)
assert(
"table" == type(padding)
)
local result = {}
local height = #pixels
local width = #pixels[1]
-- copy every pixel
for h = 1, height do
result[h] = {}
for w = 1, width do
result[h][w] = pixels[h][w]
end
end
-- pad on right side
for h = 1, height do
for a = 1, amount do
result[h][width + a] = padding
end
end
return result
end
-- Test: pixelops.pad_right() with 1-byte pixels
2023-03-17 03:39:41 +01:00
local i = {
{ { 1 }, { 0 } },
{ { 0 }, { 1 } },
{ { 1 }, { 0 } },
}
assert(
"10" == tc({i[1][1][1], i[1][2][1]}) and
"01" == tc({i[2][1][1], i[2][2][1]}) and
"10" == tc({i[3][1][1], i[3][2][1]})
)
local j = pixelops.pad_right(
2023-03-17 03:39:41 +01:00
i,
1,
{ 2 }
)
assert(
"102" == tc({j[1][1][1], j[1][2][1], j[1][3][1]}) and
"012" == tc({j[2][1][1], j[2][2][1], j[2][3][1]}) and
"102" == tc({j[3][1][1], j[3][2][1], j[3][3][1]})
)
local k = pixelops.pad_right(
2023-03-17 03:39:41 +01:00
i,
2,
{ 3 }
)
assert(
"1033" == tc({k[1][1][1], k[1][2][1], k[1][3][1], k[1][4][1]}) and
"0133" == tc({k[2][1][1], k[2][2][1], k[2][3][1], k[2][4][1]}) and
"1033" == tc({k[3][1][1], k[3][2][1], k[3][3][1], k[3][4][1]})
)
i = nil
j = nil
k = nil