178 lines
4.8 KiB
Lua
Executable File
178 lines
4.8 KiB
Lua
Executable File
#!/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)
|
|
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
|
|
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)
|
|
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)
|
|
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
|
|
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)
|
|
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)
|
|
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
|
|
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)
|
|
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)
|
|
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)
|
|
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
|
|
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(
|
|
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(
|
|
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
|