--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local string = string local table = table local bit = bit local char = string.char local byte = string.byte local insert = table.insert local concat = table.concat local bor = bit.bor local bxor = bit.bxor local band = bit.band local bnot = bit.bnot local lshift = bit.lshift local rshift = bit.rshift local ceil = math.ceil local SIGNATURE = char(137, 80, 78, 71, 13, 10, 26, 10) local crc_table = {}; do local n = 0 while n < 256 do local c = n local k = 0 while k < 8 do if band(c, 1) ~= 0 then c = bxor(0xedb88320, rshift(c, 1)) else c = rshift(c, 1) end k = k + 1 end crc_table[n + 1] = c n = n + 1 end end local crc = function(buf) local c = 0xffffffff for i = 1, #buf do c = bxor(crc_table[band(bxor(c, byte(buf, i)), 0xff) + 1], rshift(c, 8)) end return bxor(c, 0xffffffff) end local dword_as_string = function(dword) return char( rshift(band(dword, 0xff000000), 24), rshift(band(dword, 0x00ff0000), 16), rshift(band(dword, 0x0000ff00), 8), band(dword, 0x000000ff) ) end local create_chunk = function(type, data, length) local CRC = crc(type .. data) return concat({ dword_as_string(length or #data), type, data, dword_as_string(CRC) }, "", 1, 4) end local create_IHDR; do local ARGS = ( -- bit depth char(8) .. -- color type: 6=truecolor with alpha char(6) .. -- compression method: 0=deflate, only allowed value char(0) .. -- filtering: 0=adaptive, only allowed value char(0) .. -- interlacing: 0=none char(0) ) create_IHDR = function(w, h) return create_chunk("IHDR", concat({ dword_as_string(w), dword_as_string(h), ARGS }, "", 1, 3), 13) end end local deflate_pack; do local BASE = 6552 local NMAX = 5552 local adler32 = function(str) local s1 = 1 local s2 = 0 local n = NMAX for i = 1, #str do s1 = s1 + byte(str, i) s2 = s2 + s1 n = n - 1 if n == 0 then s1 = s1 % BASE s2 = s2 % BASE n = NMAX end end s1 = s1 % BASE s2 = s2 % BASE return bor(lshift(s2, 16), s1) end local splitChunks = function(chunk, chunkSize) local len = ceil(#chunk / chunkSize) local ret = {} for i = 1, len do ret[i - 1] = chunk:sub(((i - 1) * chunkSize) + 1, chunkSize) end return ret end deflate_pack = function(str) local ret = {"\x78\x9c"} local chunks = splitChunks(str, 0xFFFF) local len = #chunks local i = 0 while i < (len + 1) do local chunk = chunks[i] local chunk_n = #chunk insert(ret, i < len and "\x00" or "\x01") insert(ret, char(band(chunk_n, 0xff), band(rshift(chunk_n, 8), 0xff))) insert(ret, char(band(bnot(chunk_n), 0xff), band(rshift(bnot(chunk_n), 8), 0xff))) insert(ret, chunk) i = i + 1 end local t = adler32(str) t = char( band(rshift(t, 24), 0xff), band(rshift(t, 16), 0xff), band(rshift(t, 8), 0xff), band(t, 0xff) ) insert(ret, t) return concat(ret) end end local create_IDAT; do local slice = function(a, s, e) local ret, j = {}, 0 for i = s, e - 1 do ret[j] = char(band(a[i] or 0, 0xFF)) j = j + 1 end return ret end local array_split_chunks = function(w, h, array, chunkSize) local ret = {} local i = 0 local len = ceil((w * h * 4 + 4) / chunkSize) while i < len do ret[i] = slice(array, i * chunkSize, (i + 1) * chunkSize) i = i + 1 end return ret end create_IDAT = function(w, h, chunk) local scanlines = array_split_chunks(w, h, chunk, w * 4) local image_bytes = {} for i = 0, #scanlines do local scanline = scanlines[i] insert(image_bytes, char(band(0, 0xFF))) insert(image_bytes, concat(scanline, "", 0, #scanline)) end image_bytes = deflate_pack(concat(image_bytes)) return create_chunk("IDAT", image_bytes) end end local IEND = create_chunk("IEND", "", 0) local to_return = {SIGNATURE, nil, nil, IEND} local generate_png = function(w, h, chunk) local IHDR = create_IHDR(w, h) local IDAT = create_IDAT(w, h, chunk) to_return[2] = IHDR to_return[3] = IDAT return concat(to_return, "", 1, 4) end return generate_png