Advertisement
MainMotherboard

Network Frame

May 18th, 2021
3,866
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local s = {}
  2. s.rs = game:GetService"RunService"
  3. local convert = function(url,pngimage)
  4. local pngimage = pngimage
  5. if not pngimage then
  6. pngimage = game:HttpGet(url)
  7. end
  8. print(url,pngimage)
  9.  
  10.     local errored = false
  11.     local imageBytes = {};
  12.     local pixelsize = 1; -- Pixel size, keep at 1 for smoothness.
  13.  
  14.     local transparentcolor = Color3.fromRGB(255,255,255); -- Transparent objects render as white, set a specific color for them and it should work out. Set the variable to "nil" to
  15.  
  16.     local PNG = {}
  17.     PNG.__index = PNG
  18.  
  19.     local chunks = {};
  20.     local function IDAT(file, chunk)
  21.         local crc = chunk.CRC
  22.         local hash = file.Hash or 0
  23.  
  24.         local data = chunk.Data
  25.         local buffer = data.Buffer
  26.  
  27.         file.Hash = bit32.bxor(hash, crc)
  28.         file.ZlibStream = file.ZlibStream .. buffer
  29.     end
  30.     chunks['IDAT'] = IDAT;
  31.  
  32.     local function IEND(file)
  33.         file.Reading = nil
  34.     end
  35.     chunks['IEND'] = IEND;
  36.  
  37.     local function IHDR(file, chunk)
  38.         local data = chunk.Data
  39.  
  40.         file.Width = data:ReadInt32();
  41.         file.Height = data:ReadInt32();
  42.  
  43.         file.BitDepth = data:ReadByte();
  44.         file.ColorType = data:ReadByte();
  45.  
  46.         file.Methods =
  47.             {
  48.                 Compression = data:ReadByte();
  49.                 Filtering   = data:ReadByte();
  50.                 Interlace   = data:ReadByte();
  51.             }
  52.     end
  53.  
  54.  
  55.     chunks['IHDR'] = IHDR;
  56.  
  57.     local function PLTE(file, chunk)
  58.         if not file.Palette then
  59.             file.Palette = {}
  60.         end
  61.  
  62.         local data = chunk.Data
  63.         local palette = data:ReadAllBytes()
  64.  
  65.         if #palette % 3 ~= 0 then
  66.             error("PNG - Invalid PLTE chunk.")
  67.         end
  68.  
  69.         for i = 1, #palette, 3 do
  70.             local r = palette[i]
  71.             local g = palette[i + 1]
  72.             local b = palette[i + 2]
  73.  
  74.             local color = Color3.fromRGB(r, g, b)
  75.             local index = #file.Palette + 1
  76.  
  77.             file.Palette[index] = color
  78.         end
  79.     end
  80.  
  81.  
  82.     chunks['PLTE'] = PLTE;
  83.  
  84.     local function bKGD(file, chunk)
  85.         local data = chunk.Data
  86.  
  87.         local bitDepth = file.BitDepth
  88.         local colorType = file.ColorType
  89.  
  90.         bitDepth = (2 ^ bitDepth) - 1
  91.  
  92.         if colorType == 3 then
  93.             local index = data:ReadByte()
  94.             file.BackgroundColor = file.Palette[index]
  95.         elseif colorType == 0 or colorType == 4 then
  96.             local gray = data:ReadUInt16() / bitDepth
  97.             file.BackgroundColor = Color3.fromHSV(0, 0, gray)
  98.         elseif colorType == 2 or colorType == 6 then
  99.             local r = data:ReadUInt16() / bitDepth
  100.             local g = data:ReadUInt16() / bitDepth
  101.             local b = data:ReadUInt16() / bitDepth
  102.             file.BackgroundColor = Color3.new(r, g, b)
  103.         end
  104.     end
  105.  
  106.     chunks['bKGD'] = bKGD;
  107.  
  108.     local colors = {"White", "Red", "Green", "Blue"}
  109.  
  110.     local function cHRM(file, chunk)
  111.         local chrome = {}
  112.         local data = chunk.Data
  113.  
  114.         for i = 1, 4 do
  115.             local color = colors[i]
  116.  
  117.             chrome[color] =
  118.                 {
  119.                     [1] = data:ReadUInt32() / 10e4;
  120.                     [2] = data:ReadUInt32() / 10e4;
  121.                 }
  122.         end
  123.  
  124.         file.Chromaticity = chrome
  125.     end
  126.  
  127.     chunks['cHRM'] = cHRM;
  128.  
  129.     local function gAMA(file, chunk)
  130.         local data = chunk.Data
  131.         local value = data:ReadUInt32()
  132.         file.Gamma = value / 10e4
  133.     end
  134.  
  135.     chunks['gAMA'] = gAMA;
  136.  
  137.     local function sRGB(file, chunk)
  138.         local data = chunk.Data
  139.         file.RenderIntent = data:ReadByte()
  140.     end
  141.  
  142.     chunks['sRGB'] = sRGB;
  143.  
  144.     local function tEXt(file, chunk)
  145.         local data = chunk.Data
  146.         local key, value = "", ""
  147.  
  148.         for byte in data:IterateBytes() do
  149.             local char = string.char(byte)
  150.  
  151.             if char == '\0' then
  152.                 key = value
  153.                 value = ""
  154.             else
  155.                 value = value .. char
  156.             end
  157.         end
  158.  
  159.         file.Metadata[key] = value
  160.     end
  161.  
  162.     chunks['tEXt'] = tEXt;
  163.  
  164.     local function tIME(file, chunk)
  165.         local data = chunk.Data
  166.  
  167.         local timeStamp =
  168.             {
  169.                 Year  = data:ReadUInt16();
  170.                 Month = data:ReadByte();
  171.                 Day   = data:ReadByte();
  172.  
  173.                 Hour   = data:ReadByte();
  174.                 Minute = data:ReadByte();
  175.                 Second = data:ReadByte();
  176.             }
  177.  
  178.         file.TimeStamp = timeStamp
  179.     end
  180.  
  181.     chunks['tIME'] = tIME;
  182.  
  183.     local function tRNS(file, chunk)
  184.         local data = chunk.Data
  185.  
  186.         local bitDepth = file.BitDepth
  187.         local colorType = file.ColorType
  188.  
  189.         bitDepth = (2 ^ bitDepth) - 1
  190.  
  191.         if colorType == 3 then
  192.             local palette = file.Palette
  193.             local alphaMap = {}
  194.  
  195.             for i = 1, #palette do
  196.                 local alpha = data:ReadByte()
  197.  
  198.                 if not alpha then
  199.                     alpha = 255
  200.                 end
  201.  
  202.                 alphaMap[i] = alpha
  203.             end
  204.  
  205.             file.AlphaData = alphaMap
  206.         elseif colorType == 0 then
  207.             local grayAlpha = data:ReadUInt16()
  208.             file.Alpha = grayAlpha / bitDepth
  209.         elseif colorType == 2 then
  210.             -- TODO: This seems incorrect...
  211.             local r = data:ReadUInt16() / bitDepth
  212.             local g = data:ReadUInt16() / bitDepth
  213.             local b = data:ReadUInt16() / bitDepth
  214.             file.Alpha = Color3.new(r, g, b)
  215.         else
  216.  
  217.             local errored = "PNG - Invalid tRNS chunk"
  218.         end
  219.     end
  220.  
  221.  
  222.     chunks['tRNS'] = tRNS;
  223.  
  224.     local Deflate = {}
  225.  
  226.     local band = bit32.band
  227.     local lshift = bit32.lshift
  228.     local rshift = bit32.rshift
  229.  
  230.     local BTYPE_NO_COMPRESSION = 0
  231.     local BTYPE_FIXED_HUFFMAN = 1
  232.     local BTYPE_DYNAMIC_HUFFMAN = 2
  233.  
  234.     local lens = -- Size base for length codes 257..285
  235.         {
  236.             [0] = 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
  237.             35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
  238.         }
  239.  
  240.     local lext = -- Extra bits for length codes 257..285
  241.         {
  242.             [0] = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
  243.             3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
  244.         }
  245.  
  246.     local dists = -- Offset base for distance codes 0..29
  247.         {
  248.             [0] = 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
  249.             257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
  250.             8193, 12289, 16385, 24577
  251.         }
  252.  
  253.     local dext = -- Extra bits for distance codes 0..29
  254.         {
  255.             [0] = 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
  256.             7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
  257.             12, 12, 13, 13
  258.         }
  259.  
  260.     local order = -- Permutation of code length codes
  261.         {
  262.             16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
  263.             11, 4, 12, 3, 13, 2, 14, 1, 15
  264.         }
  265.  
  266.     -- Fixed literal table for BTYPE_FIXED_HUFFMAN
  267.     local fixedLit = {0, 8, 144, 9, 256, 7, 280, 8, 288}
  268.  
  269.     -- Fixed distance table for BTYPE_FIXED_HUFFMAN
  270.     local fixedDist = {0, 5, 32}
  271.  
  272.     local function createState(bitStream)
  273.         local state =
  274.             {
  275.                 Output = bitStream;
  276.                 Window = {};
  277.                 Pos = 1;
  278.             }
  279.  
  280.         return state
  281.     end
  282.  
  283.     local function write(state, byte)
  284.         local pos = state.Pos
  285.         state.Output(byte)
  286.         state.Window[pos] = byte
  287.         state.Pos = pos % 32768 + 1  -- 32K
  288.     end
  289.  
  290.     local function memoize(fn)
  291.         local meta = {}
  292.         local memoizer = setmetatable({}, meta)
  293.  
  294.         function meta:__index(k)
  295.             local v = fn(k)
  296.             memoizer[k] = v
  297.  
  298.             return v
  299.         end
  300.  
  301.         return memoizer
  302.     end
  303.  
  304.     -- small optimization (lookup table for powers of 2)
  305.     local pow2 = memoize(function (n)
  306.         return 2 ^ n
  307.     end)
  308.  
  309.     -- weak metatable marking objects as bitstream type
  310.     local isBitStream = setmetatable({}, { __mode = 'k' })
  311.  
  312.     local function createBitStream(reader)
  313.         local buffer = 0
  314.         local bitsLeft = 0
  315.  
  316.         local stream = {}
  317.         isBitStream[stream] = true
  318.  
  319.         function stream:GetBitsLeft()
  320.             return bitsLeft
  321.         end
  322.  
  323.         function stream:Read(count)
  324.             count = count or 1
  325.  
  326.             while bitsLeft < count do
  327.                 local byte = reader:ReadByte()
  328.  
  329.                 if not byte then
  330.                     return
  331.                 end
  332.  
  333.                 buffer = buffer + lshift(byte, bitsLeft)
  334.                 bitsLeft = bitsLeft + 8
  335.             end
  336.  
  337.             local bits
  338.  
  339.             if count == 0 then
  340.                 bits = 0
  341.             elseif count == 32 then
  342.                 bits = buffer
  343.                 buffer = 0
  344.             else
  345.                 bits = band(buffer, rshift(2^32 - 1, 32 - count))
  346.                 buffer = rshift(buffer, count)
  347.             end
  348.  
  349.             bitsLeft = bitsLeft - count
  350.             return bits
  351.         end
  352.  
  353.         return stream
  354.     end
  355.  
  356.     local function getBitStream(obj)
  357.         if isBitStream[obj] then
  358.             return obj
  359.         end
  360.  
  361.         return createBitStream(obj)
  362.     end
  363.  
  364.     local function sortHuffman(a, b)
  365.         return a.NumBits == b.NumBits and a.Value < b.Value or a.NumBits < b.NumBits
  366.     end
  367.  
  368.     local function msb(bits, numBits)
  369.         local res = 0
  370.  
  371.         for i = 1, numBits do
  372.             res = lshift(res, 1) + band(bits, 1)
  373.             bits = rshift(bits, 1)
  374.         end
  375.  
  376.         return res
  377.     end
  378.  
  379.     local function createHuffmanTable(init, isFull)
  380.         local hTable = {}
  381.  
  382.         if isFull then
  383.             for val, numBits in pairs(init) do
  384.                 if numBits ~= 0 then
  385.                     hTable[#hTable + 1] =
  386.                         {
  387.                             Value = val;
  388.                             NumBits = numBits;
  389.                         }
  390.                 end
  391.             end
  392.         else
  393.             for i = 1, #init - 2, 2 do
  394.                 local firstVal = init[i]
  395.  
  396.                 local numBits = init[i + 1]
  397.                 local nextVal = init[i + 2]
  398.  
  399.                 if numBits ~= 0 then
  400.                     for val = firstVal, nextVal - 1 do
  401.                         hTable[#hTable + 1] =
  402.                             {
  403.                                 Value = val;
  404.                                 NumBits = numBits;
  405.                             }
  406.                     end
  407.                 end
  408.             end
  409.         end
  410.  
  411.         table.sort(hTable, sortHuffman)
  412.  
  413.         local code = 1
  414.         local numBits = 0
  415.  
  416.         for i, slide in ipairs(hTable) do
  417.             if slide.NumBits ~= numBits then
  418.                 code = code * pow2[slide.NumBits - numBits]
  419.                 numBits = slide.NumBits
  420.             end
  421.  
  422.             slide.Code = code
  423.             code = code + 1
  424.         end
  425.  
  426.         local minBits = math.huge
  427.         local look = {}
  428.  
  429.         for i, slide in ipairs(hTable) do
  430.             minBits = math.min(minBits, slide.NumBits)
  431.             look[slide.Code] = slide.Value
  432.         end
  433.  
  434.         local firstCode = memoize(function (bits)
  435.             return pow2[minBits] + msb(bits, minBits)
  436.         end)
  437.  
  438.         function hTable:Read(bitStream)
  439.             local code = 1 -- leading 1 marker
  440.             local numBits = 0
  441.  
  442.             while true do
  443.                 if numBits == 0 then  -- small optimization (optional)
  444.                     local index = bitStream:Read(minBits)
  445.                     numBits = numBits + minBits
  446.                     code = firstCode[index]
  447.                 else
  448.                     local bit = bitStream:Read()
  449.                     numBits = numBits + 1
  450.                     code = code * 2 + bit -- MSB first
  451.                 end
  452.  
  453.                 local val = look[code]
  454.  
  455.                 if val then
  456.                     return val
  457.                 end
  458.             end
  459.         end
  460.  
  461.         return hTable
  462.     end
  463.  
  464.     local function parseZlibHeader(bitStream)
  465.         -- Compression Method
  466.         local cm = bitStream:Read(4)
  467.  
  468.         -- Compression info
  469.         local cinfo = bitStream:Read(4)  
  470.  
  471.         -- FLaGs: FCHECK (check bits for CMF and FLG)  
  472.         local fcheck = bitStream:Read(5)
  473.  
  474.         -- FLaGs: FDICT (present dictionary)
  475.         local fdict = bitStream:Read(1)
  476.  
  477.         -- FLaGs: FLEVEL (compression level)
  478.         local flevel = bitStream:Read(2)
  479.  
  480.         -- CMF (Compresion Method and flags)
  481.         local cmf = cinfo * 16  + cm
  482.  
  483.         -- FLaGs
  484.         local flg = fcheck + fdict * 32 + flevel * 64
  485.  
  486.         if cm ~= 8 then -- not "deflate"
  487.             error("unrecognized zlib compression method: " .. cm)
  488.         end
  489.  
  490.         if cinfo > 7 then
  491.             error("invalid zlib window size: cinfo=" .. cinfo)
  492.         end
  493.  
  494.         local windowSize = 2 ^ (cinfo + 8)
  495.  
  496.         if (cmf * 256 + flg) % 31 ~= 0 then
  497.             error("invalid zlib header (bad fcheck sum)")
  498.         end
  499.  
  500.         if fdict == 1 then
  501.             error("FIX:TODO - FDICT not currently implemented")
  502.         end
  503.  
  504.         return windowSize
  505.     end
  506.  
  507.     local function parseHuffmanTables(bitStream)
  508.         local numLits  = bitStream:Read(5) -- # of literal/length codes - 257
  509.         local numDists = bitStream:Read(5) -- # of distance codes - 1
  510.         local numCodes = bitStream:Read(4) -- # of code length codes - 4
  511.  
  512.         local codeLens = {}
  513.  
  514.         for i = 1, numCodes + 4 do
  515.             local index = order[i]
  516.             codeLens[index] = bitStream:Read(3)
  517.         end
  518.  
  519.         codeLens = createHuffmanTable(codeLens, true)
  520.  
  521.         local function decode(numCodes)
  522.             local init = {}
  523.             local numBits
  524.             local val = 0
  525.  
  526.             while val < numCodes do
  527.                 local codeLen = codeLens:Read(bitStream)
  528.                 local numRepeats
  529.  
  530.                 if codeLen <= 15 then
  531.                     numRepeats = 1
  532.                     numBits = codeLen
  533.                 elseif codeLen == 16 then
  534.                     numRepeats = 3 + bitStream:Read(2)
  535.                 elseif codeLen == 17 then
  536.                     numRepeats = 3 + bitStream:Read(3)
  537.                     numBits = 0
  538.                 elseif codeLen == 18 then
  539.                     numRepeats = 11 + bitStream:Read(7)
  540.                     numBits = 0
  541.                 end
  542.  
  543.                 for i = 1, numRepeats do
  544.                     init[val] = numBits
  545.                     val = val + 1
  546.                 end
  547.             end
  548.  
  549.             return createHuffmanTable(init, true)
  550.         end
  551.  
  552.         local numLitCodes = numLits + 257
  553.         local numDistCodes = numDists + 1
  554.  
  555.         local litTable = decode(numLitCodes)
  556.         local distTable = decode(numDistCodes)
  557.  
  558.         return litTable, distTable
  559.     end
  560.  
  561.     local function parseCompressedItem(bitStream, state, litTable, distTable)
  562.         local val = litTable:Read(bitStream)
  563.  
  564.         if val < 256 then -- literal
  565.             write(state, val)
  566.         elseif val == 256 then -- end of block
  567.             return true
  568.         else
  569.             local lenBase = lens[val - 257]
  570.             local numExtraBits = lext[val - 257]
  571.  
  572.             local extraBits = bitStream:Read(numExtraBits)
  573.             local len = lenBase + extraBits
  574.  
  575.             local distVal = distTable:Read(bitStream)
  576.             local distBase = dists[distVal]
  577.  
  578.             local distNumExtraBits = dext[distVal]
  579.             local distExtraBits = bitStream:Read(distNumExtraBits)
  580.  
  581.             local dist = distBase + distExtraBits
  582.  
  583.             for i = 1, len do
  584.                 local pos = (state.Pos - 1 - dist) % 32768 + 1
  585.                 local byte = assert(state.Window[pos], "invalid distance")
  586.                 write(state, byte)
  587.             end
  588.         end
  589.  
  590.         return false
  591.     end
  592.  
  593.     local function parseBlock(bitStream, state)
  594.         local bFinal = bitStream:Read(1)
  595.         local bType = bitStream:Read(2)
  596.  
  597.         if bType == BTYPE_NO_COMPRESSION then
  598.             local left = bitStream:GetBitsLeft()
  599.             bitStream:Read(left)
  600.  
  601.             local len = bitStream:Read(16)
  602.             local nlen = bitStream:Read(16)
  603.  
  604.             for i = 1, len do
  605.                 local byte = bitStream:Read(8)
  606.                 write(state, byte)
  607.             end
  608.         elseif bType == BTYPE_FIXED_HUFFMAN or bType == BTYPE_DYNAMIC_HUFFMAN then
  609.             local litTable, distTable
  610.  
  611.             if bType == BTYPE_DYNAMIC_HUFFMAN then
  612.                 litTable, distTable = parseHuffmanTables(bitStream)
  613.             else
  614.                 litTable = createHuffmanTable(fixedLit)
  615.                 distTable = createHuffmanTable(fixedDist)
  616.             end
  617.  
  618.             repeat until parseCompressedItem(bitStream, state, litTable, distTable)
  619.         else
  620.             error("unrecognized compression type")
  621.         end
  622.  
  623.         return bFinal ~= 0
  624.     end
  625.  
  626.     function Deflate:Inflate(io)
  627.         local state = createState(io.Output)
  628.         local bitStream = getBitStream(io.Input)
  629.  
  630.         repeat until parseBlock(bitStream, state)
  631.     end
  632.  
  633.     function Deflate:InflateZlib(io)
  634.         local bitStream = getBitStream(io.Input)
  635.         local windowSize = parseZlibHeader(bitStream)
  636.  
  637.         self:Inflate
  638.         {
  639.             Input = bitStream;
  640.             Output = io.Output;
  641.         }
  642.  
  643.         local bitsLeft = bitStream:GetBitsLeft()
  644.         bitStream:Read(bitsLeft)
  645.     end
  646.  
  647.     local Unfilter = {}
  648.  
  649.     function Unfilter:None(scanline, pixels, bpp, row)
  650.         for i = 1, #scanline do
  651.             pixels[row][i] = scanline[i]
  652.         end
  653.     end
  654.  
  655.     function Unfilter:Sub(scanline, pixels, bpp, row)
  656.         for i = 1, bpp do
  657.             pixels[row][i] = scanline[i]
  658.         end
  659.  
  660.         for i = bpp + 1, #scanline do
  661.             local x = scanline[i]
  662.             local a = pixels[row][i - bpp]
  663.             pixels[row][i] = bit32.band(x + a, 0xFF)
  664.         end
  665.     end
  666.  
  667.     function Unfilter:Up(scanline, pixels, bpp, row)
  668.         if row > 1 then
  669.             local upperRow = pixels[row - 1]
  670.  
  671.             for i = 1, #scanline do
  672.                 local x = scanline[i]
  673.                 local b = upperRow[i]
  674.                 pixels[row][i] = bit32.band(x + b, 0xFF)
  675.             end
  676.         else
  677.             self:None(scanline, pixels, bpp, row)
  678.         end
  679.     end
  680.  
  681.     function Unfilter:Average(scanline, pixels, bpp, row)
  682.         if row > 1 then
  683.             for i = 1, bpp do
  684.                 local x = scanline[i]
  685.                 local b = pixels[row - 1][i]
  686.  
  687.                 b = bit32.rshift(b, 1)
  688.                 pixels[row][i] = bit32.band(x + b, 0xFF)
  689.             end
  690.  
  691.             for i = bpp + 1, #scanline do
  692.                 local x = scanline[i]
  693.                 local b = pixels[row - 1][i]
  694.  
  695.                 local a = pixels[row][i - bpp]
  696.                 local ab = bit32.rshift(a + b, 1)
  697.  
  698.                 pixels[row][i] = bit32.band(x + ab, 0xFF)
  699.             end
  700.         else
  701.             for i = 1, bpp do
  702.                 pixels[row][i] = scanline[i]
  703.             end
  704.  
  705.             for i = bpp + 1, #scanline do
  706.                 local x = scanline[i]
  707.                 local b = pixels[row - 1][i]
  708.  
  709.                 b = bit32.rshift(b, 1)
  710.                 pixels[row][i] = bit32.band(x + b, 0xFF)
  711.             end
  712.         end
  713.     end
  714.  
  715.     function Unfilter:Paeth(scanline, pixels, bpp, row)
  716.         if row > 1 then
  717.             local pr
  718.  
  719.             for i = 1, bpp do
  720.                 local x = scanline[i]
  721.                 local b = pixels[row - 1][i]
  722.                 pixels[row][i] = bit32.band(x + b, 0xFF)
  723.             end
  724.  
  725.             for i = bpp + 1, #scanline do
  726.                 local a = pixels[row][i - bpp]
  727.                 local b = pixels[row - 1][i]
  728.                 local c = pixels[row - 1][i - bpp]
  729.  
  730.                 local x = scanline[i]
  731.                 local p = a + b - c
  732.  
  733.                 local pa = math.abs(p - a)
  734.                 local pb = math.abs(p - b)
  735.                 local pc = math.abs(p - c)
  736.  
  737.                 if pa <= pb and pa <= pc then
  738.                     pr = a
  739.                 elseif pb <= pc then
  740.                     pr = b
  741.                 else
  742.                     pr = c
  743.                 end
  744.  
  745.                 pixels[row][i] = bit32.band(x + pr, 0xFF)
  746.             end
  747.         else
  748.             self:Sub(scanline, pixels, bpp, row)
  749.         end
  750.     end
  751.  
  752.  
  753.     local BinaryReader = {}
  754.     BinaryReader.__index = BinaryReader
  755.  
  756.     function BinaryReader.new(buffer)
  757.         local reader =
  758.             {
  759.                 Position = 1;
  760.                 Buffer = buffer;
  761.                 Length = #buffer;
  762.             }
  763.  
  764.         return setmetatable(reader, BinaryReader)
  765.     end
  766.  
  767.     function BinaryReader:ReadByte()
  768.         local buffer = self.Buffer
  769.         local pos = self.Position
  770.  
  771.         if pos <= self.Length then
  772.             local result = buffer:sub(pos, pos)
  773.             self.Position = pos + 1
  774.  
  775.             return result:byte()
  776.         end
  777.     end
  778.  
  779.     function BinaryReader:ReadBytes(count, asArray)
  780.         local values = {}
  781.  
  782.         for i = 1, count do
  783.             values[i] = self:ReadByte()
  784.         end
  785.  
  786.         if asArray then
  787.             return values
  788.         end
  789.  
  790.         return unpack(values)
  791.     end
  792.  
  793.     function BinaryReader:ReadAllBytes()
  794.         return self:ReadBytes(self.Length, true)
  795.     end
  796.  
  797.     function BinaryReader:IterateBytes()
  798.         return function ()
  799.             return self:ReadByte()
  800.         end
  801.     end
  802.  
  803.     function BinaryReader:TwosComplementOf(value, numBits)
  804.         if value >= (2 ^ (numBits - 1)) then
  805.             value = value - (2 ^ numBits)
  806.         end
  807.  
  808.         return value
  809.     end
  810.  
  811.     function BinaryReader:ReadUInt16()
  812.         local upper, lower = self:ReadBytes(2)
  813.         return (upper * 256) + lower
  814.     end
  815.  
  816.     function BinaryReader:ReadInt16()
  817.         local unsigned = self:ReadUInt16()
  818.         return self:TwosComplementOf(unsigned, 16)
  819.     end
  820.  
  821.     function BinaryReader:ReadUInt32()
  822.         local upper = self:ReadUInt16()
  823.         local lower = self:ReadUInt16()
  824.  
  825.         return (upper * 65536) + lower
  826.     end
  827.  
  828.     function BinaryReader:ReadInt32()
  829.         local unsigned = self:ReadUInt32()
  830.         return self:TwosComplementOf(unsigned, 32)
  831.     end
  832.  
  833.     function BinaryReader:ReadString(length)
  834.         if length == nil then
  835.             length = self:ReadByte()
  836.         end
  837.  
  838.         local pos = self.Position
  839.         local nextPos = math.min(self.Length, pos + length)
  840.  
  841.         local result = self.Buffer:sub(pos, nextPos - 1)
  842.         self.Position = nextPos
  843.  
  844.         return result
  845.     end
  846.  
  847.     function BinaryReader:ForkReader(length)
  848.         local chunk = self:ReadString(length)
  849.         return BinaryReader.new(chunk)
  850.     end
  851.  
  852.  
  853.     local function getBytesPerPixel(colorType)
  854.         if colorType == 0 or colorType == 3 then
  855.             return 1
  856.         elseif colorType == 4 then
  857.             return 2
  858.         elseif colorType == 2 then
  859.             return 3
  860.         elseif colorType == 6 then
  861.             return 4
  862.         else
  863.             return 0
  864.         end
  865.     end
  866.  
  867.     local function clampInt(value, min, max)
  868.         local num = tonumber(value) or 0
  869.         num = math.floor(num + .5)
  870.  
  871.         return math.clamp(num, min, max)
  872.     end
  873.  
  874.     local function indexBitmap(file, x, y)
  875.         local width = file.Width
  876.         local height = file.Height
  877.  
  878.         local x = clampInt(x, 1, width)
  879.         local y = clampInt(y, 1, height)
  880.  
  881.         local bitmap = file.Bitmap
  882.         local bpp = file.BytesPerPixel
  883.  
  884.         local i0 = ((x - 1) * bpp) + 1
  885.         local i1 = i0 + bpp
  886.  
  887.         return bitmap[y], i0, i1
  888.     end
  889.  
  890.     function PNG:GetPixel(t,x, y)
  891.         local row, i0, i1 = indexBitmap(t, x, y)
  892.         local colorType = t.ColorType
  893.         self = t;
  894.  
  895.         local color, alpha do
  896.             if colorType == 0 then
  897.                 local gray = unpack(row, i0, i1)
  898.                 color = Color3.fromHSV(0, 0, gray)
  899.                 alpha = 255
  900.             elseif colorType == 2 then
  901.                 local r, g, b = unpack(row, i0, i1)
  902.                 color = Color3.fromRGB(r, g, b)
  903.                 alpha = 255
  904.             elseif colorType == 3 then
  905.                 local palette = self.Palette
  906.                 local alphaData = self.AlphaData
  907.  
  908.                 local index = unpack(row, i0, i1)
  909.                 index = index + 1
  910.  
  911.                 if palette then
  912.                     color = palette[index]
  913.                 end
  914.  
  915.                 if alphaData then
  916.                     alpha = alphaData[index]
  917.                 end
  918.             elseif colorType == 4 then
  919.                 local gray, a = unpack(row, i0, i1)
  920.                 color = Color3.fromHSV(0, 0, gray)
  921.                 alpha = a
  922.             elseif colorType == 6 then
  923.                 local r, g, b, a = unpack(row, i0, i1)
  924.                 color = Color3.fromRGB(r, g, b, a)
  925.                 alpha = a
  926.             end
  927.         end
  928.  
  929.         if not color then
  930.             color = Color3.new()
  931.         end
  932.  
  933.         if not alpha then
  934.             alpha = 255
  935.         end
  936.  
  937.         return color, alpha
  938.     end
  939.  
  940.     function PNG.new(buffer)
  941.         -- Create the reader.
  942.         local reader = BinaryReader.new(buffer)
  943.  
  944.         -- Create the file object.
  945.         local file =
  946.             {
  947.                 Chunks = {};
  948.                 Metadata = {};
  949.  
  950.                 Reading = true;
  951.                 ZlibStream = "";
  952.             }
  953.  
  954.         -- Verify the file header.
  955.         local header = reader:ReadString(8)
  956.  
  957.         if header ~= "\137PNG\r\n\26\n" then
  958.             local errored = "PNG - Input data is not a PNG file."
  959.         end
  960.  
  961.         while file.Reading do
  962.             local length = reader:ReadInt32()
  963.             local chunkType = reader:ReadString(4)
  964.  
  965.             local data, crc
  966.  
  967.             if length > 0 then
  968.                 data = reader:ForkReader(length)
  969.                 crc = reader:ReadUInt32()
  970.             end
  971.  
  972.             local chunk =
  973.                 {
  974.                     Length = length;
  975.                     Type = chunkType;
  976.  
  977.                     Data = data;
  978.                     CRC = crc;
  979.                 }
  980.  
  981.             local handler = chunks[chunkType];
  982.  
  983.             if handler then
  984.                 handler(file, chunk)
  985.             end
  986.  
  987.             table.insert(file.Chunks, chunk)
  988.         end
  989.  
  990.         -- Decompress the zlib stream.
  991.         local success, response = pcall(function ()
  992.             local result = {}
  993.             local index = 0
  994.  
  995.             Deflate:InflateZlib
  996.             {
  997.                 Input = BinaryReader.new(file.ZlibStream);
  998.  
  999.                 Output = function (byte)
  1000.                     index = index + 1
  1001.                     result[index] = string.char(byte)
  1002.                 end
  1003.             }
  1004.  
  1005.             return table.concat(result)
  1006.         end)
  1007.  
  1008.         if not success then
  1009.             local errored = "PNG - Unable to unpack PNG data. " .. tostring(response)
  1010.         end
  1011.  
  1012.         -- Grab expected info from the file.
  1013.  
  1014.         local width = file.Width
  1015.         local height = file.Height
  1016.  
  1017.         local bitDepth = file.BitDepth
  1018.         local colorType = file.ColorType
  1019.  
  1020.         local buffer = BinaryReader.new(response)
  1021.         file.ZlibStream = nil
  1022.  
  1023.         local bitmap = {}
  1024.         file.Bitmap = bitmap
  1025.  
  1026.         local channels = getBytesPerPixel(colorType)
  1027.         file.NumChannels = channels
  1028.  
  1029.         local bpp = math.max(1, channels * (bitDepth / 8))
  1030.         file.BytesPerPixel = bpp
  1031.  
  1032.         -- Unfilter the buffer and
  1033.         -- load it into the bitmap.
  1034.  
  1035.         for row = 1, height do 
  1036.             local filterType = buffer:ReadByte()
  1037.             local scanline = buffer:ReadBytes(width * bpp, true)
  1038.  
  1039.             bitmap[row] = {}
  1040.  
  1041.             if filterType == 0 then
  1042.                 -- None
  1043.                 Unfilter:None(scanline, bitmap, bpp, row)
  1044.             elseif filterType == 1 then
  1045.                 -- Sub
  1046.                 Unfilter:Sub(scanline, bitmap, bpp, row)
  1047.             elseif filterType == 2 then
  1048.                 -- Up
  1049.                 Unfilter:Up(scanline, bitmap, bpp, row)
  1050.             elseif filterType == 3 then
  1051.                 -- Average
  1052.                 Unfilter:Average(scanline, bitmap, bpp, row)
  1053.             elseif filterType == 4 then
  1054.                 -- Paeth
  1055.                 Unfilter:Paeth(scanline, bitmap, bpp, row)
  1056.             end
  1057.         end
  1058.  
  1059.         return setmetatable(file, PNG)
  1060.     end
  1061.  
  1062.  
  1063.     local result = PNG.new(pngimage)
  1064.     local pixels = {};
  1065.     local yy = 0;
  1066.     local xy = Vector2.new()
  1067.     local skip = 0
  1068.     for yy = 1,result.Height do
  1069.     for xx = 1,result.Width do
  1070.             if skip >= 8000 then
  1071.                 skip = 0
  1072.                 s.rs.Stepped:Wait()
  1073.             end
  1074.             skip=skip+1
  1075.             xy=Vector2.new(xx,yy)
  1076.             local color,alpha = PNG:GetPixel(result,xx,yy)
  1077.             imageBytes[tostring(Vector2.new(xx,yy))]={x = xx,y=yy, r = color.R,g = color.G,b = color.B,a = alpha*0.00392156862}
  1078.         end
  1079.     end
  1080.         return {image = imageBytes,size = Vector2.new(result.Width,result.Height)}
  1081.  
  1082. end
  1083. return convert
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement