Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- LuaLZW (https://github.com/Rochet2/lualzw/blob/master/lualzw.lua) tweaked for use in potatOS compression
- --[[
- MIT License
- Copyright (c) 2016 Rochet2
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- ]]
- --[[
- MIT License
- Copyright (c) 2016 Rochet2
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- ]]
- local char = string.char
- local type = type
- local select = select
- local sub = string.sub
- local tconcat = table.concat
- local basedictcompress = {}
- local basedictdecompress = {}
- for i = 0, 255 do
- local ic, iic = char(i), char(i, 0)
- basedictcompress[ic] = iic
- basedictdecompress[iic] = ic
- end
- local function dictAddA(str, dict, a, b)
- if a >= 256 then
- a, b = 0, b+1
- if b >= 256 then
- dict = {}
- b = 1
- end
- end
- dict[str] = char(a,b)
- a = a+1
- return dict, a, b
- end
- local function compress(input)
- if type(input) ~= "string" then
- error("string expected, got "..type(input))
- end
- local len = #input
- if len <= 1 then
- return false
- end
- local dict = {}
- local a, b = 0, 1
- local result = {}
- local resultlen = 0
- local n = 1
- local word = ""
- for i = 1, len do
- local c = sub(input, i, i)
- local wc = word..c
- if not (basedictcompress[wc] or dict[wc]) then
- local write = basedictcompress[word] or dict[word]
- if not write then
- error "algorithm error, could not fetch word"
- end
- result[n] = write
- resultlen = resultlen + #write
- n = n+1
- if len <= resultlen then
- return false
- end
- dict, a, b = dictAddA(wc, dict, a, b)
- word = c
- else
- word = wc
- end
- end
- result[n] = basedictcompress[word] or dict[word]
- resultlen = resultlen+#result[n]
- n = n+1
- if len <= resultlen then
- return false
- end
- return tconcat(result)
- end
- local function dictAddB(str, dict, a, b)
- if a >= 256 then
- a, b = 0, b+1
- if b >= 256 then
- dict = {}
- b = 1
- end
- end
- dict[char(a,b)] = str
- a = a+1
- return dict, a, b
- end
- local function decompress(input)
- if type(input) ~= "string" then
- return false, "string expected, got "..type(input)
- end
- local len = #input
- if len < 2 then
- return false, "invalid input - not a compressed string"
- end
- local dict = {}
- local a, b = 0, 1
- local result = {}
- local n = 1
- local last = sub(input, 1, 2)
- result[n] = basedictdecompress[last] or dict[last]
- n = n+1
- for i = 3, len, 2 do
- local code = sub(input, i, i+1)
- local lastStr = basedictdecompress[last] or dict[last]
- if not lastStr then
- return false, "could not find last from dict. Invalid input?"
- end
- local toAdd = basedictdecompress[code] or dict[code]
- if toAdd then
- result[n] = toAdd
- n = n+1
- dict, a, b = dictAddB(lastStr..sub(toAdd, 1, 1), dict, a, b)
- else
- local tmp = lastStr..sub(lastStr, 1, 1)
- result[n] = tmp
- n = n+1
- dict, a, b = dictAddB(tmp, dict, a, b)
- end
- last = code
- end
- return tconcat(result)
- end
- return {
- compress = compress,
- decompress = decompress,
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement