Advertisement
ToxicTheBoss

png

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