Advertisement
brianops1

ehh

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