51 {
52 int dstLen = 4, bitCount;
53 byte control;
54
55 byte* sPtr = (byte*) srcAddr;
56 int matchLength, matchOffset = 0;
58
59
60 Memory.Fill(_First, 0x40000, 0xFF);
61 _wIndex = _wLength = 0;
62
63
64 CompressionHeader header = new CompressionHeader
65 {
67 ExpandedSize = (uint) srcLen,
68 IsExtendedLZ77 = extFmt
69 };
70 outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0));
71
72 List<byte> blockBuffer;
73 int lastUpdate = srcLen;
74 int remaining = srcLen;
75
76 progress?.
Begin(0, remaining, 0);
77
78 while (remaining > 0)
79 {
80 blockBuffer = new List<byte> {0};
81 for (bitCount = 0, control = 0; bitCount < 8 && remaining > 0; bitCount++)
82 {
83 control <<= 1;
84 if ((matchLength = FindPattern(sPtr, remaining, ref matchOffset)) != 0)
85 {
86 int length;
87 if (extFmt)
88 {
89 if (matchLength >= 0xFF + 0xF + 3)
90 {
91 length = matchLength - 0xFF - 0xF - 3;
92 blockBuffer.Add((byte) (0x10 | (length >> 12)));
93 blockBuffer.Add((byte) (length >> 4));
94 }
95 else if (matchLength >= 0xF + 2)
96 {
97 length = matchLength - 0xF - 2;
98 blockBuffer.Add((byte) (length >> 4));
99 }
100 else
101 {
102 length = matchLength - 1;
103 }
104 }
105 else
106 {
107 length = matchLength - 3;
108 }
109
110 control |= 1;
111 blockBuffer.Add((byte) ((length << 4) | ((matchOffset - 1) >> 8)));
112 blockBuffer.Add((byte) (matchOffset - 1));
113 }
114 else
115 {
116 matchLength = 1;
117 blockBuffer.Add(*sPtr);
118 }
119
120 Consume(sPtr, matchLength, remaining);
121 sPtr += matchLength;
122 remaining -= matchLength;
123 }
124
125
126 control <<= 8 - bitCount;
127
128
129 blockBuffer[0] = control;
130 outStream.Write(blockBuffer.ToArray(), 0, blockBuffer.Count);
131 dstLen += blockBuffer.Count;
132
133 if (progress != null)
134 {
135 if (lastUpdate - remaining > 0x4000)
136 {
137 lastUpdate = remaining;
138 progress.
Update(srcLen - remaining);
139 }
140 }
141 }
142
143 outStream.Flush();
144
146
147 return dstLen;
148 }
int PatternLength
Definition: LZ77.cs:16
CompressionType
Definition: CompressionHeader.cs:9