diff options
Diffstat (limited to 'src/lzss/lzssencoder.nim')
-rw-r--r-- | src/lzss/lzssencoder.nim | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/src/lzss/lzssencoder.nim b/src/lzss/lzssencoder.nim index 82fbe7b..36e0c7e 100644 --- a/src/lzss/lzssencoder.nim +++ b/src/lzss/lzssencoder.nim | |||
@@ -14,20 +14,18 @@ | |||
14 | # You should have received a copy of the GNU Affero General Public License | 14 | # You should have received a copy of the GNU Affero General Public License |
15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | 15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | import lists | 17 | import matchtable, lzssnode, lzsschain |
18 | import listpolyfill, matchtable, lzssnode, lzsschain | ||
19 | 18 | ||
20 | const matchGroupLength* = 3 | 19 | const matchGroupLength* = 3 |
21 | const maxRefByteLength = high(uint8).int + matchGroupLength | 20 | const maxRefByteLength = high(uint8).int + matchGroupLength |
22 | let emptySinglyLinkedList = initSinglyLinkedList[int]() | ||
23 | 21 | ||
24 | proc commonPrefixLength*(a, b: openArray[uint8], skipFirst, maxLength: int): int = | 22 | proc commonPrefixLength*(a, b: openArray[uint8], skipFirst, maxLength: int): int = |
25 | result = skipFirst | 23 | result = skipFirst |
26 | let maxPrefixLength = min(min(a.len, b.len), maxLength) | 24 | let maxPrefixLength = min(min(a.len, b.len), maxLength) |
27 | while result < maxPrefixLength and a[result] == b[result]: result += 1 | 25 | while result < maxPrefixLength and a[result] == b[result]: result += 1 |
28 | 26 | ||
29 | proc longestPrefix*(candidatePos: SinglyLinkedList[int], searchBuf, lookAheadBuf: openArray[uint8]): tuple[length, pos: int] = | 27 | proc longestPrefix*(candidatePos: openArray[int], searchBuf, lookAheadBuf: openArray[uint8]): tuple[length, pos: int] = |
30 | for startIndex in candidatePos.items: | 28 | for startIndex in candidatePos: |
31 | let prefixLength = commonPrefixLength( | 29 | let prefixLength = commonPrefixLength( |
32 | searchBuf.toOpenArray(startIndex, searchBuf.len - 1), lookAheadBuf, matchGroupLength, maxRefByteLength) | 30 | searchBuf.toOpenArray(startIndex, searchBuf.len - 1), lookAheadBuf, matchGroupLength, maxRefByteLength) |
33 | if prefixLength > result.length: result = (prefixLength, startIndex) | 31 | if prefixLength > result.length: result = (prefixLength, startIndex) |
@@ -39,20 +37,20 @@ proc addGroups*(matchTable: MatchTable[seq[uint8], int], buffer: openArray[uint8 | |||
39 | matchTable.addMatch(group, cursor) | 37 | matchTable.addMatch(group, cursor) |
40 | 38 | ||
41 | proc lzssEncode*(buf: openArray[uint8]): LzssChain = | 39 | proc lzssEncode*(buf: openArray[uint8]): LzssChain = |
42 | result = initSinglyLinkedList[LzssNode]() | 40 | result = newSeqOfCap[LzssNode](buf.len) |
43 | let matchTable = initMatchTable(seq[uint8], int) | 41 | let matchTable = initMatchTable(seq[uint8], int) |
44 | var cursor = 0 | 42 | var cursor = 0 |
45 | while cursor < buf.len() - matchGroupLength: | 43 | while cursor < buf.len() - matchGroupLength: |
46 | let matches = matchTable.matchList(buf[cursor..<(cursor + matchGroupLength)]) | 44 | let matches = matchTable.matchList(buf[cursor..<(cursor + matchGroupLength)]) |
47 | let prefix = matches.longestPrefix(buf.toOpenArray(0, cursor - 1), buf.toOpenArray(cursor, buf.len - 1)) | 45 | let prefix = matches.longestPrefix(buf.toOpenArray(0, cursor - 1), buf.toOpenArray(cursor, buf.len - 1)) |
48 | if prefix.length > 0: | 46 | if prefix.length > 0: |
49 | result.append(lzssReference(prefix.length, cursor - prefix.pos)) | 47 | result.add(lzssReference(prefix.length, cursor - prefix.pos)) |
50 | cursor += prefix.length | 48 | cursor += prefix.length |
51 | else: | 49 | else: |
52 | result.append(lzssCharacter(buf[cursor])) | 50 | result.add(lzssCharacter(buf[cursor])) |
53 | cursor += 1 | 51 | cursor += 1 |
54 | if cursor - prefix.length >= matchGroupLength: | 52 | if cursor - prefix.length >= matchGroupLength: |
55 | matchTable.addGroups(buf, cursor - prefix.length - matchGroupLength, cursor) | 53 | matchTable.addGroups(buf, cursor - prefix.length - matchGroupLength, cursor) |
56 | while cursor < buf.len: | 54 | while cursor < buf.len: |
57 | result.append(lzssCharacter(buf[cursor])) | 55 | result.add(lzssCharacter(buf[cursor])) |
58 | cursor += 1 | 56 | cursor += 1 |