Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[----------------------------------------------------------------------------
- LZSS - encoder / decoder
- This is free and unencumbered software released into the public domain.
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
- 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 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.
- For more information, please refer to <http://unlicense.org/>
- --]]----------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- local M = {}
- local string, table = string, table
- --------------------------------------------------------------------------------
- local POS_BITS = 12
- local LEN_BITS = 16 - POS_BITS
- local POS_SIZE = 1 << POS_BITS
- local LEN_SIZE = 1 << LEN_BITS
- local LEN_MIN = 3
- --------------------------------------------------------------------------------
- function M.compress(input)
- local offset, output = 1, {}
- local window = ''
- local function search()
- for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
- local str = string.sub(input, offset, offset + i - 1)
- local pos = string.find(window, str, 1, true)
- if pos then
- return pos, str
- end
- end
- end
- while offset <= #input do
- local flags, buffer = 0, {}
- for i = 0, 7 do
- if offset <= #input then
- local pos, str = search()
- if pos and #str >= LEN_MIN then
- local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
- buffer[#buffer + 1] = string.pack('>I2', tmp)
- else
- flags = flags | (1 << i)
- str = string.sub(input, offset, offset)
- buffer[#buffer + 1] = str
- end
- window = string.sub(window .. str, -POS_SIZE)
- offset = offset + #str
- else
- break
- end
- end
- if #buffer > 0 then
- output[#output + 1] = string.char(flags)
- output[#output + 1] = table.concat(buffer)
- end
- end
- return table.concat(output)
- end
- --------------------------------------------------------------------------------
- function M.decompress(input)
- local offset, output = 1, {}
- local window = ''
- while offset <= #input do
- local flags = string.byte(input, offset)
- offset = offset + 1
- for i = 1, 8 do
- local str = nil
- if (flags & 1) ~= 0 then
- if offset <= #input then
- str = string.sub(input, offset, offset)
- offset = offset + 1
- end
- else
- if offset + 1 <= #input then
- local tmp = string.unpack('>I2', input, offset)
- offset = offset + 2
- local pos = (tmp >> LEN_BITS) + 1
- local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
- str = string.sub(window, pos, pos + len - 1)
- end
- end
- flags = flags >> 1
- if str then
- output[#output + 1] = str
- window = string.sub(window .. str, -POS_SIZE)
- end
- end
- end
- return table.concat(output)
- end
- return {
- mode = "rb",
- loadfile = function(file, env)
- local hand = package.filesystem.open(file, "rb")
- local data = ""
- local lc = " "
- while lc and lc ~= "" do
- lc = hand:read(math.huge)
- data = data .. (lc or "")
- end
- hand:close()
- return load(M.decompress(data:sub(5)), "="..file, "t", env)
- end,
- load = function(hand, env)
- local data = ""
- local lc = " "
- while lc and lc ~= "" do
- lc = hand:read(math.huge)
- data = data .. (lc or "")
- end
- hand:close()
- return load(M.decompress(data:sub(5)), "="..os.getenv("_"), env)
- end,
- info = function()
- print(" Loads LZSS compressed Lua files.")
- end,
- version = "1.0"
- }
Add Comment
Please, Sign In to add comment