96 {
97 _pSrc = (byte*) srcAddr;
98 _sourceLen = srcLen;
99
100 int chunkCount = (int) Math.Ceiling((double) srcLen / _threadChunk);
101
102 progress?.
Begin(0, srcLen, 0);
103
104 _contractions = new List<Contraction>[chunkCount];
105
106 bool YAY0Comp = type == 1;
107
108 if (type == 0)
109 {
110 YAZ0 header = new YAZ0
111 {
112 _tag = YAZ0.Tag,
113 _unCompDataLen = (uint) _sourceLen
114 };
115 outStream.Write(&header, YAZ0.Size);
116 }
117 else if (type == 1)
118 {
119
120
121 }
122 else
123 {
124 CompressionHeader header = new CompressionHeader
125 {
127 ExpandedSize = (uint) _sourceLen
128 };
129 outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0));
130 }
131
132 ParallelLoopResult result = Parallel.For(0, chunkCount, FindContractions);
133
134 while (!result.IsCompleted)
135 {
136 Thread.Sleep(100);
137 }
138
139 List<Contraction> fullContractions;
140 int codeBits, current;
141 byte codeByte;
142
143 int lastUpdate = srcLen;
144
145 fullContractions = new List<Contraction>();
146 for (int i = 0; i < _contractions.Length; i++)
147 {
148 fullContractions.AddRange(_contractions[i]);
149 _contractions[i].Clear();
150 _contractions[i] = null;
151 }
152
153 _contractions = null;
154
155
156 codeBits = 0;
157 codeByte = 0;
158 current = 0;
159
160 List<byte> tempCounts = new List<byte>();
161 List<byte> tempData = new List<byte>();
162 List<byte> codes = new List<byte>();
163 List<List<byte>> counts = new List<List<byte>>();
164 List<List<byte>> data = new List<List<byte>>();
165
166 for (int i = 0; i < srcLen;)
167 {
168 if (codeBits == 8)
169 {
170 codes.Add(codeByte);
171 counts.Add(tempCounts);
172 data.Add(tempData);
173
174 tempCounts = new List<byte>();
175 tempData = new List<byte>();
176
177 codeBits = 0;
178 codeByte = 0;
179 }
180
181 if (current < fullContractions.Count && fullContractions[current].Location == i)
182 {
183 if (fullContractions[current].Size >= 0x12)
184 {
185 byte
186 b1 = (byte) (fullContractions[current].Offset >> 8),
187 b2 = (byte) (fullContractions[current].Offset & 0xFF);
188
189 if (YAY0Comp)
190 {
191 tempCounts.Add(b1);
192 tempCounts.Add(b2);
193 }
194 else
195 {
196 tempData.Add(b1);
197 tempData.Add(b2);
198 }
199
200 tempData.Add((byte) (fullContractions[current].Size - 0x12));
201 }
202 else
203 {
204 byte
205 b1 = (byte) ((fullContractions[current].Offset >> 8) |
206 ((fullContractions[current].Size - 2) << 4)),
207 b2 = (byte) (fullContractions[current].Offset & 0xFF);
208
209 if (YAY0Comp)
210 {
211 tempCounts.Add(b1);
212 tempCounts.Add(b2);
213 }
214 else
215 {
216 tempData.Add(b1);
217 tempData.Add(b2);
218 }
219 }
220
221 i += fullContractions[current++].Size;
222
223 while (current < fullContractions.Count && fullContractions[current].Location < i)
224 {
225 current++;
226 }
227 }
228 else
229 {
230 codeByte |= (byte) (1 << (7 - codeBits));
231 tempData.Add(_pSrc[i++]);
232 }
233
234 codeBits++;
235
236 if (progress != null)
237 {
238 if (i % 0x4000 == 0)
239 {
241 }
242 }
243 }
244
245 codes.Add(codeByte);
246 counts.Add(tempCounts);
247 data.Add(tempData);
248
249 if (YAY0Comp)
250 {
251
252 YAY0 header = new YAY0
253 {
254 _tag = YAY0.Tag,
255 _unCompDataLen = (uint) _sourceLen
256 };
257 uint offset = 0x10 + (uint) codes.Count;
258 header._countOffset = offset;
259 foreach (List<byte> list in counts)
260 {
261 offset += (uint) list.Count;
262 }
263
264 header._dataOffset = offset;
265 outStream.Write(&header, YAY0.Size);
266
267
268 foreach (byte c in codes)
269 {
270 outStream.WriteByte(c);
271 }
272
273
274 foreach (List<byte> list in counts)
275 {
276 outStream.Write(list.ToArray(), 0, list.Count);
277 }
278
279
280 foreach (List<byte> list in data)
281 {
282 outStream.Write(list.ToArray(), 0, list.Count);
283 }
284 }
285 else
286 {
287 for (int i = 0; i < codes.Count; i++)
288 {
289
290 outStream.WriteByte(codes[i]);
291
292 outStream.Write(data[i].ToArray(), 0, data[i].Count);
293 }
294 }
295
296 outStream.Flush();
297
299
300 return (int) outStream.Length;
301 }
CompressionType
Definition: CompressionHeader.cs:9