Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | unit ZMExtrLZ7719; |
2 | |||
3 | (* |
||
4 | ZMExtrLZ7719.pas - LZ77 stream expander |
||
5 | Copyright (C) 2009, 2010 by Russell J. Peters, Roger Aelbrecht, |
||
6 | Eric W. Engler and Chris Vleghert. |
||
7 | |||
8 | This file is part of TZipMaster Version 1.9. |
||
9 | |||
10 | TZipMaster is free software: you can redistribute it and/or modify |
||
11 | it under the terms of the GNU Lesser General Public License as published by |
||
12 | the Free Software Foundation, either version 3 of the License, or |
||
13 | (at your option) any later version. |
||
14 | |||
15 | TZipMaster is distributed in the hope that it will be useful, |
||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | GNU Lesser General Public License for more details. |
||
19 | |||
20 | You should have received a copy of the GNU Lesser General Public License |
||
21 | along with TZipMaster. If not, see <http://www.gnu.org/licenses/>. |
||
22 | |||
23 | contact: problems@delphizip.org (include ZipMaster in the subject). |
||
24 | updates: http://www.delphizip.org |
||
25 | DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip |
||
26 | |||
27 | modified 2007-11-05 |
||
28 | ---------------------------------------------------------------------------*) |
||
29 | |||
30 | interface |
||
31 | |||
32 | uses |
||
33 | Classes; |
||
34 | |||
35 | // expects src at orig_size (integer), data (bytes) |
||
36 | function LZ77Extract(dst, src: TStream; size: integer): integer; |
||
37 | |||
38 | implementation |
||
39 | |||
40 | const |
||
41 | N = 4096; |
||
42 | NMask = $FFF; //(N-1) |
||
43 | F = 16; |
||
44 | |||
45 | function GetByte(var bytes: Integer; Src: TStream): Integer; |
||
46 | var |
||
47 | cb: Byte; |
||
48 | begin |
||
49 | Result := -1; |
||
50 | if (bytes > 4) and (Src.Size > Src.Position) then |
||
51 | begin |
||
52 | dec(bytes); |
||
53 | if Src.Read(cb, 1) = 1 then |
||
54 | Result := Integer(cb) |
||
55 | else |
||
56 | bytes := 0; |
||
57 | end; |
||
58 | end; |
||
59 | |||
60 | function LZ77Extract(dst, src: TStream; size: integer): integer; |
||
61 | var |
||
62 | bits: Integer; |
||
63 | Buffer: array of Byte; |
||
64 | bytes: integer; |
||
65 | ch: Integer; |
||
66 | File_Size: integer; |
||
67 | i: Integer; |
||
68 | j: Integer; |
||
69 | len: Integer; |
||
70 | mask: Integer; |
||
71 | written: integer; |
||
72 | begin |
||
73 | bytes := size; |
||
74 | if bytes < 0 then |
||
75 | bytes := HIGH(Integer); |
||
76 | src.ReadBuffer(File_Size, sizeof(integer)); |
||
77 | written := 0; |
||
78 | |||
79 | SetLength(Buffer, N); |
||
80 | i := N - F; |
||
81 | while True do |
||
82 | begin |
||
83 | bits := GetByte(bytes, src); |
||
84 | if (bits < 0) then |
||
85 | break; |
||
86 | |||
87 | mask := 1; |
||
88 | while mask < 256 do |
||
89 | begin |
||
90 | if (bits and mask) = 0 then |
||
91 | begin |
||
92 | j := GetByte(bytes, src); |
||
93 | if j < 0 then |
||
94 | break; |
||
95 | len := GetByte(bytes, src); |
||
96 | inc(j, (len and $F0) shl 4); |
||
97 | len := (len and 15) + 3; |
||
98 | while len > 0 do |
||
99 | begin |
||
100 | Buffer[i] := Buffer[j]; |
||
101 | dst.WriteBuffer(Buffer[i], 1); |
||
102 | inc(written); |
||
103 | j := succ(j) and NMask; |
||
104 | i := succ(i) and NMask; |
||
105 | dec(len); |
||
106 | end; |
||
107 | end |
||
108 | else |
||
109 | begin |
||
110 | ch := GetByte(bytes, src); |
||
111 | if ch < 0 then |
||
112 | break; |
||
113 | Buffer[i] := Byte(ch {and 255}); |
||
114 | dst.WriteBuffer(ch, 1); |
||
115 | inc(written); |
||
116 | i := succ(i) and NMask; |
||
117 | end; |
||
118 | inc(mask, mask); |
||
119 | end; |
||
120 | end; |
||
121 | if (File_Size = written) and (bytes = 4) then |
||
122 | Result := 0 // good |
||
123 | else |
||
124 | if bytes = 4 then |
||
125 | Result := -2 // wrong length |
||
126 | else |
||
127 | Result := -1; // invalid data |
||
128 | Buffer := nil; |
||
129 | end; |
||
130 | |||
131 | end. |