Advertisement
osmarks

lualzw for potatOS

Apr 17th, 2020
534
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.39 KB | None | 0 0
  1. -- LuaLZW (https://github.com/Rochet2/lualzw/blob/master/lualzw.lua) tweaked for use in potatOS compression
  2.  
  3. --[[
  4. MIT License
  5.  
  6. Copyright (c) 2016 Rochet2
  7.  
  8. Permission is hereby granted, free of charge, to any person obtaining a copy
  9. of this software and associated documentation files (the "Software"), to deal
  10. in the Software without restriction, including without limitation the rights
  11. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. copies of the Software, and to permit persons to whom the Software is
  13. furnished to do so, subject to the following conditions:
  14.  
  15. The above copyright notice and this permission notice shall be included in all
  16. copies or substantial portions of the Software.
  17.  
  18. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24. SOFTWARE.
  25. ]]
  26.  
  27. --[[
  28. MIT License
  29.  
  30. Copyright (c) 2016 Rochet2
  31.  
  32. Permission is hereby granted, free of charge, to any person obtaining a copy
  33. of this software and associated documentation files (the "Software"), to deal
  34. in the Software without restriction, including without limitation the rights
  35. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  36. copies of the Software, and to permit persons to whom the Software is
  37. furnished to do so, subject to the following conditions:
  38.  
  39. The above copyright notice and this permission notice shall be included in all
  40. copies or substantial portions of the Software.
  41.  
  42. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  43. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  44. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  45. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  46. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  47. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  48. SOFTWARE.
  49. ]]
  50.  
  51. local char = string.char
  52. local type = type
  53. local select = select
  54. local sub = string.sub
  55. local tconcat = table.concat
  56.  
  57. local basedictcompress = {}
  58. local basedictdecompress = {}
  59. for i = 0, 255 do
  60.     local ic, iic = char(i), char(i, 0)
  61.     basedictcompress[ic] = iic
  62.     basedictdecompress[iic] = ic
  63. end
  64.  
  65. local function dictAddA(str, dict, a, b)
  66.     if a >= 256 then
  67.         a, b = 0, b+1
  68.         if b >= 256 then
  69.             dict = {}
  70.             b = 1
  71.         end
  72.     end
  73.     dict[str] = char(a,b)
  74.     a = a+1
  75.     return dict, a, b
  76. end
  77.  
  78. local function compress(input)
  79.     if type(input) ~= "string" then
  80.         error("string expected, got "..type(input))
  81.     end
  82.     local len = #input
  83.     if len <= 1 then
  84.         return false
  85.     end
  86.  
  87.     local dict = {}
  88.     local a, b = 0, 1
  89.  
  90.     local result = {}
  91.     local resultlen = 0
  92.     local n = 1
  93.     local word = ""
  94.     for i = 1, len do
  95.         local c = sub(input, i, i)
  96.         local wc = word..c
  97.         if not (basedictcompress[wc] or dict[wc]) then
  98.             local write = basedictcompress[word] or dict[word]
  99.             if not write then
  100.                 error "algorithm error, could not fetch word"
  101.             end
  102.             result[n] = write
  103.             resultlen = resultlen + #write
  104.             n = n+1
  105.             if  len <= resultlen then
  106.                 return false
  107.             end
  108.             dict, a, b = dictAddA(wc, dict, a, b)
  109.             word = c
  110.         else
  111.             word = wc
  112.         end
  113.     end
  114.     result[n] = basedictcompress[word] or dict[word]
  115.     resultlen = resultlen+#result[n]
  116.     n = n+1
  117.     if  len <= resultlen then
  118.         return false
  119.     end
  120.     return tconcat(result)
  121. end
  122.  
  123. local function dictAddB(str, dict, a, b)
  124.     if a >= 256 then
  125.         a, b = 0, b+1
  126.         if b >= 256 then
  127.             dict = {}
  128.             b = 1
  129.         end
  130.     end
  131.     dict[char(a,b)] = str
  132.     a = a+1
  133.     return dict, a, b
  134. end
  135.  
  136. local function decompress(input)
  137.     if type(input) ~= "string" then
  138.         return false, "string expected, got "..type(input)
  139.     end
  140.  
  141.     local len = #input
  142.  
  143.     if len < 2 then
  144.         return false, "invalid input - not a compressed string"
  145.     end
  146.  
  147.     local dict = {}
  148.     local a, b = 0, 1
  149.  
  150.     local result = {}
  151.     local n = 1
  152.     local last = sub(input, 1, 2)
  153.     result[n] = basedictdecompress[last] or dict[last]
  154.     n = n+1
  155.     for i = 3, len, 2 do
  156.         local code = sub(input, i, i+1)
  157.         local lastStr = basedictdecompress[last] or dict[last]
  158.         if not lastStr then
  159.             return false, "could not find last from dict. Invalid input?"
  160.         end
  161.         local toAdd = basedictdecompress[code] or dict[code]
  162.         if toAdd then
  163.             result[n] = toAdd
  164.             n = n+1
  165.             dict, a, b = dictAddB(lastStr..sub(toAdd, 1, 1), dict, a, b)
  166.         else
  167.             local tmp = lastStr..sub(lastStr, 1, 1)
  168.             result[n] = tmp
  169.             n = n+1
  170.             dict, a, b = dictAddB(tmp, dict, a, b)
  171.         end
  172.         last = code
  173.     end
  174.     return tconcat(result)
  175. end
  176.  
  177. return {
  178.     compress = compress,
  179.     decompress = decompress,
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement