Advertisement
ou1z

Untitled

Jul 25th, 2021 (edited)
852
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.63 KB | None | 0 0
  1. -- The MIT License (MIT)
  2.  
  3. -- Copyright (c) 2013 DelusionalLogic
  4.  
  5. -- Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. -- this software and associated documentation files (the "Software"), to deal in
  7. -- the Software without restriction, including without limitation the rights to
  8. -- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. -- the Software, and to permit persons to whom the Software is furnished to do so,
  10. -- subject to the following conditions:
  11.  
  12. -- The above copyright notice and this permission notice shall be included in all
  13. -- copies or substantial portions of the Software.
  14.  
  15. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. -- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. -- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. -- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. -- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  
  22. local deflate = loadstring(game:HttpGet("https://pastebin.com/raw/S9t6PdY7"))()
  23. local requiredDeflateVersion = "0.3.20111128"
  24.  
  25. if (deflate._VERSION ~= requiredDeflateVersion) then
  26.     error("Incorrect deflate version: must be "..requiredDeflateVersion..", not "..deflate._VERSION)
  27. end
  28.  
  29. local function bsRight(num, pow)
  30.     return math.floor(num / 2^pow)
  31. end
  32.  
  33. local function bsLeft(num, pow)
  34.     return math.floor(num * 2^pow)
  35. end
  36.  
  37. local function bytesToNum(bytes)
  38.     local n = 0
  39.     for k,v in ipairs(bytes) do
  40.         n = bsLeft(n, 8) + v
  41.     end
  42.     if (n > 2147483647) then
  43.         return (n - 4294967296)
  44.     else
  45.         return n
  46.     end
  47.     n = (n > 2147483647) and (n - 4294967296) or n
  48.     return n
  49. end
  50.  
  51. local function readInt(stream, bps)
  52.     local bytes = {}
  53.     bps = bps or 4
  54.     for i=1,bps do
  55.         bytes[i] = stream:sub(1,1):byte()
  56.     end
  57.     return bytesToNum(bytes)
  58. end
  59.  
  60. local function readChar(stream, num)
  61.     num = num or 1
  62.     return stream:sub(num,num)
  63. end
  64.  
  65. local function readByte(stream)
  66.     return stream:sub(1,1):byte()
  67. end
  68.  
  69. local function getDataIHDR(stream, length)
  70.     local data = {}
  71.     data["width"] = readInt(stream)
  72.     data["height"] = readInt(stream)
  73.     data["bitDepth"] = readByte(stream)
  74.     data["colorType"] = readByte(stream)
  75.     data["compression"] = readByte(stream)
  76.     data["filter"] = readByte(stream)
  77.     data["interlace"] = readByte(stream)
  78.     return data
  79. end
  80.  
  81. local function getDataIDAT(stream, length, oldData)
  82.     local data = {}
  83.     if (oldData == nil) then
  84.         data.data = readChar(stream, length)
  85.     else
  86.         data.data = oldData.data .. readChar(stream, length)
  87.     end
  88.     return data
  89. end
  90.  
  91. local function getDataPLTE(stream, length)
  92.     local data = {}
  93.     data["numColors"] = math.floor(length/3)
  94.     data["colors"] = {}
  95.     for i = 1, data["numColors"] do
  96.         data.colors[i] = {
  97.             R = readByte(stream),
  98.             G = readByte(stream),
  99.             B = readByte(stream)
  100.         }
  101.     end
  102.     return data
  103. end
  104.  
  105. local function extractChunkData(stream)
  106.     local chunkData = {}
  107.     local length
  108.     local type
  109.     local crc
  110.  
  111.     while type ~= "IEND" do
  112.         length = readInt(stream)
  113.         type = readChar(stream, 4)
  114.         if (type == "IHDR") then
  115.             chunkData[type] = getDataIHDR(stream, length)
  116.         elseif (type == "IDAT") then
  117.             chunkData[type] = getDataIDAT(stream, length, chunkData[type])
  118.         elseif (type == "PLTE") then
  119.             chunkData[type] = getDataPLTE(stream, length)
  120.         else
  121.             readChar(stream, length)
  122.         end
  123.         crc = readChar(stream, 4)
  124.     end
  125.  
  126.     return chunkData
  127. end
  128.  
  129. local function makePixel(stream, depth, colorType, palette)
  130.     local bps = math.floor(depth/8) --bits per sample
  131.     local pixelData = { R = 0, G = 0, B = 0, A = 0 }
  132.     local grey
  133.     local index
  134.     local color
  135.  
  136.     if colorType == 0 then
  137.         grey = readInt(stream, bps)
  138.         pixelData.R = grey
  139.         pixelData.G = grey
  140.         pixelData.B = grey
  141.         pixelData.A = 255
  142.     elseif colorType == 2 then
  143.         pixelData.R = readInt(stream, bps)
  144.         pixelData.G = readInt(stream, bps)
  145.         pixelData.B = readInt(stream, bps)
  146.         pixelData.A = 255
  147.     elseif colorType == 3 then
  148.         index = readInt(stream, bps)+1
  149.         color = palette.colors[index]
  150.         pixelData.R = color.R
  151.         pixelData.G = color.G
  152.         pixelData.B = color.B
  153.         pixelData.A = 255
  154.     elseif colorType == 4 then
  155.         grey = readInt(stream, bps)
  156.         pixelData.R = grey
  157.         pixelData.G = grey
  158.         pixelData.B = grey
  159.         pixelData.A = readInt(stream, bps)
  160.     elseif colorType == 6 then
  161.         pixelData.R = readInt(stream, bps)
  162.         pixelData.G = readInt(stream, bps)
  163.         pixelData.B = readInt(stream, bps)
  164.         pixelData.A = readInt(stream, bps)
  165.     end
  166.  
  167.     return pixelData
  168. end
  169.  
  170. local function bitFromColorType(colorType)
  171.     if colorType == 0 then return 1 end
  172.     if colorType == 2 then return 3 end
  173.     if colorType == 3 then return 1 end
  174.     if colorType == 4 then return 2 end
  175.     if colorType == 6 then return 4 end
  176.     error 'Invalid colortype'
  177. end
  178.  
  179. local function paethPredict(a, b, c)
  180.     local p = a + b - c
  181.     local varA = math.abs(p - a)
  182.     local varB = math.abs(p - b)
  183.     local varC = math.abs(p - c)
  184.  
  185.     if varA <= varB and varA <= varC then
  186.         return a
  187.     elseif varB <= varC then
  188.         return b
  189.     else
  190.         return c
  191.     end
  192. end
  193.  
  194. local function filterType1(curPixel, lastPixel)
  195.     local lastByte
  196.     local newPixel = {}
  197.     for fieldName, curByte in pairs(curPixel) do
  198.         lastByte = lastPixel and lastPixel[fieldName] or 0
  199.         newPixel[fieldName] = (curByte + lastByte) % 256
  200.     end
  201.     return newPixel
  202. end
  203.  
  204. local prevPixelRow = {}
  205. local function getPixelRow(stream, depth, colorType, palette, length)
  206.     local pixelRow = {}
  207.     local bpp = math.floor(depth/8) * bitFromColorType(colorType)
  208.     local bpl = bpp*length
  209.     local filterType = readByte(stream)
  210.  
  211.     if filterType == 0 then
  212.         for x = 1, length do
  213.             pixelRow[x] = makePixel(stream, depth, colorType, palette)
  214.         end
  215.     elseif filterType == 1 then
  216.         local curPixel
  217.         local lastPixel
  218.         local newPixel
  219.         local lastByte
  220.         for x = 1, length do
  221.             curPixel = makePixel(stream, depth, colorType, palette)
  222.             lastPixel = prevPixelRow[pixelNum]
  223.             newPixel = {}
  224.             for fieldName, curByte in pairs(curPixel) do
  225.                 lastByte = lastPixel and lastPixel[fieldName] or 0
  226.                 newPixel[fieldName] = (curByte + lastByte) % 256
  227.             end
  228.             pixelRow[x] = newPixel
  229.         end
  230.     else
  231.         error("Unsupported filter type: " .. tostring(filterType))
  232.     end
  233.     prevPixelRow = pixelRow
  234.  
  235.     return pixelRow
  236. end
  237.  
  238.  
  239. local function pngImage(path, progCallback, verbose, memSave)
  240.     local stream = readfile(path)
  241.     local chunkData
  242.     local imStr
  243.     local width = 0
  244.     local height = 0
  245.     local depth = 0
  246.     local colorType = 0
  247.     local output = {}
  248.     local pixels = {}
  249.     local StringStream
  250.     local function printV(msg)
  251.         if (verbose) then
  252.             print(msg)
  253.         end
  254.     end
  255.  
  256.  
  257.     printV("Parsing Chunks...")
  258.     chunkData = extractChunkData(stream)
  259.  
  260.     width = chunkData.IHDR.width
  261.     height = chunkData.IHDR.height
  262.     depth = chunkData.IHDR.bitDepth
  263.     colorType = chunkData.IHDR.colorType
  264.  
  265.     printV("Deflating...")
  266.     deflate.inflate_zlib {
  267.         input = chunkData.IDAT.data,
  268.         output = function(byte)
  269.             output[#output+1] = string.char(byte)
  270.         end,
  271.         disable_crc = true
  272.     }
  273.     StringStream = {
  274.         str = table.concat(output),
  275.         read = function(self, num)
  276.             local toreturn = self.str:sub(1, num)
  277.             self.str = self.str:sub(num + 1, self.str:len())
  278.             return toreturn
  279.         end  
  280.     }
  281.  
  282.     printV("Creating pixelmap...")
  283.     for i = 1, height do
  284.         local pixelRow = getPixelRow(StringStream, depth, colorType, chunkData.PLTE, width)
  285.         if progCallback ~= nil then
  286.             progCallback(i, height, pixelRow)
  287.         end
  288.         if not memSave then
  289.             pixels[i] = pixelRow
  290.         end
  291.     end
  292.  
  293.     printV("Done.")
  294.     return {
  295.         width = width,
  296.         height = height,
  297.         depth = depth,
  298.         colorType = colorType,
  299.         pixels = pixels
  300.     }
  301. end
  302.  
  303. return pngImage
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement