public static void Expand(CompressionHeader* header, VoidPtr dstAddress, int dstLen) { uint total = 0; VoidPtr ceil = dstAddress + dstLen; if (header->Parameter != 1) { byte* pSrc = (byte*)header->Data; byte* pDst = (byte*)dstAddress; do { total += *pSrc++; *pDst++ = (byte)total; } while (pSrc < ceil); } else { bushort* pSrc = (bushort*)header->Data; bushort* pDst = (bushort*)dstAddress; do { total += *pSrc++; *pDst++ = (ushort)total; } while (pSrc < ceil); } }
public static void Expand(CompressionHeader* header, VoidPtr dstAddr, int dstLen) { switch (header->Algorithm) { case CompressionType.LZ77: case CompressionType.ExtendedLZ77: { LZ77.Expand(header, dstAddr, dstLen); break; } case CompressionType.RunLength: { RunLength.Expand(header, dstAddr, dstLen); break; } //case CompressionType.Huffman: { Huffman.Expand(header, dstAddr, dstLen); break; } //case CompressionType.Differential: { Differential.Expand(header, dstAddr, dstLen); break; } default: throw new InvalidCompressionException("Unknown compression type."); } }
public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, bool extFmt) { int dstLen = 4, bitCount; byte control; byte *sPtr = (byte *)srcAddr; int matchLength, matchOffset = 0; PatternLength = extFmt ? 0xFFFF + 0xFF + 0xF + 3 : 0xF + 3; //Initialize Memory.Fill(_First, 0x40000, 0xFF); _wIndex = _wLength = 0; //Write header CompressionHeader header = new CompressionHeader { Algorithm = CompressionType.LZ77, ExpandedSize = (uint)srcLen, IsExtendedLZ77 = extFmt }; outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0)); List <byte> blockBuffer; int lastUpdate = srcLen; int remaining = srcLen; progress?.Begin(0, remaining, 0); while (remaining > 0) { blockBuffer = new List <byte> { 0 }; for (bitCount = 0, control = 0; bitCount < 8 && remaining > 0; bitCount++) { control <<= 1; if ((matchLength = FindPattern(sPtr, remaining, ref matchOffset)) != 0) { int length; if (extFmt) { if (matchLength >= 0xFF + 0xF + 3) { length = matchLength - 0xFF - 0xF - 3; blockBuffer.Add((byte)(0x10 | (length >> 12))); blockBuffer.Add((byte)(length >> 4)); } else if (matchLength >= 0xF + 2) { length = matchLength - 0xF - 2; blockBuffer.Add((byte)(length >> 4)); } else { length = matchLength - 1; } } else { length = matchLength - 3; } control |= 1; blockBuffer.Add((byte)((length << 4) | ((matchOffset - 1) >> 8))); blockBuffer.Add((byte)(matchOffset - 1)); } else { matchLength = 1; blockBuffer.Add(*sPtr); } Consume(sPtr, matchLength, remaining); sPtr += matchLength; remaining -= matchLength; } //Left-align bits control <<= 8 - bitCount; //Write buffer blockBuffer[0] = control; outStream.Write(blockBuffer.ToArray(), 0, blockBuffer.Count); dstLen += blockBuffer.Count; if (progress != null) { if (lastUpdate - remaining > 0x4000) { lastUpdate = remaining; progress.Update(srcLen - remaining); } } } outStream.Flush(); progress?.Finish(); return(dstLen); }
/// <param name="type">0 is YAZ0, 1 is YAY0, anything else is CompressionHeader</param> public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, int type) { _pSrc = (byte *)srcAddr; _sourceLen = srcLen; int chunkCount = (int)Math.Ceiling((double)srcLen / _threadChunk); if (progress != null) { progress.Begin(0, srcLen, 0); } _contractions = new List <Contraction> [chunkCount]; bool YAY0Comp = type == 1; if (type == 0) { YAZ0 header = new YAZ0(); header._tag = YAZ0.Tag; header._unCompDataLen = (uint)_sourceLen; outStream.Write(&header, YAZ0.Size); } else if (type == 1) { //Don't write YAY0 header yet. //Collect all compression data first } else { CompressionHeader header = new CompressionHeader(); header.Algorithm = CompressionType.RunLength; header.ExpandedSize = (uint)_sourceLen; outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0)); } ParallelLoopResult result = Parallel.For(0, chunkCount, FindContractions); while (!result.IsCompleted) { Thread.Sleep(100); } List <Contraction> fullContractions; int codeBits, current; byte codeByte; //byte[] temp; int lastUpdate = srcLen; fullContractions = new List <Contraction>(); for (int i = 0; i < _contractions.Length; i++) { fullContractions.AddRange(_contractions[i]); _contractions[i].Clear(); _contractions[i] = null; } _contractions = null; //temp = new byte[3 * 8]; codeBits = 0; codeByte = 0; current = 0; List <byte> tempCounts = new List <byte>(); List <byte> tempData = new List <byte>(); List <byte> codes = new List <byte>(); List <List <byte> > counts = new List <List <byte> >(); List <List <byte> > data = new List <List <byte> >(); for (int i = 0; i < srcLen;) { if (codeBits == 8) { codes.Add(codeByte); counts.Add(tempCounts); data.Add(tempData); tempCounts = new List <byte>(); tempData = new List <byte>(); codeBits = 0; codeByte = 0; } if (current < fullContractions.Count && fullContractions[current].Location == i) { if (fullContractions[current].Size >= 0x12) { byte b1 = (byte)(fullContractions[current].Offset >> 8), b2 = (byte)(fullContractions[current].Offset & 0xFF); if (YAY0Comp) { tempCounts.Add(b1); tempCounts.Add(b2); } else { tempData.Add(b1); tempData.Add(b2); } tempData.Add((byte)(fullContractions[current].Size - 0x12)); } else { byte b1 = (byte)((fullContractions[current].Offset >> 8) | ((fullContractions[current].Size - 2) << 4)), b2 = (byte)(fullContractions[current].Offset & 0xFF); if (YAY0Comp) { tempCounts.Add(b1); tempCounts.Add(b2); } else { tempData.Add(b1); tempData.Add(b2); } } i += fullContractions[current++].Size; while (current < fullContractions.Count && fullContractions[current].Location < i) { current++; } } else { codeByte |= (byte)(1 << (7 - codeBits)); tempData.Add(_pSrc[i++]); } codeBits++; if (progress != null) { if (i % 0x4000 == 0) { progress.Update(i); } } } codes.Add(codeByte); counts.Add(tempCounts); data.Add(tempData); if (YAY0Comp) { //Write header YAY0 header = new YAY0(); header._tag = YAY0.Tag; header._unCompDataLen = (uint)_sourceLen; uint offset = 0x10 + (uint)codes.Count; header._countOffset = offset; foreach (List <byte> list in counts) { offset += (uint)list.Count; } header._dataOffset = offset; outStream.Write(&header, YAY0.Size); //Write codes foreach (byte c in codes) { outStream.WriteByte(c); } //Write counts foreach (List <byte> list in counts) { outStream.Write(list.ToArray(), 0, list.Count); } //Write data foreach (List <byte> list in data) { outStream.Write(list.ToArray(), 0, list.Count); } } else { for (int i = 0; i < codes.Count; i++) { //Write code outStream.WriteByte(codes[i]); //Write data outStream.Write(data[i].ToArray(), 0, data[i].Count); } } outStream.Flush(); if (progress != null) { progress.Finish(); } return((int)outStream.Length); }
public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, bool extFmt) { int dstLen = 4, bitCount; byte control; byte* sPtr = (byte*)srcAddr; int matchLength, matchOffset = 0; PatternLength = extFmt ? (0xFFFF + 0xFF + 0xF + 3) : (0xF + 3); //Initialize Memory.Fill(_First, 0x40000, 0xFF); _wIndex = _wLength = 0; //Write header CompressionHeader header = new CompressionHeader(); header.Algorithm = CompressionType.LZ77; header.ExpandedSize = (int)srcLen; header.IsExtendedLZ77 = extFmt; outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0)); List<byte> blockBuffer; int lastUpdate = srcLen; int remaining = srcLen; if (progress != null) progress.Begin(0, remaining, 0); while (remaining > 0) { blockBuffer = new List<byte>() { 0 }; for (bitCount = 0, control = 0; (bitCount < 8) && (remaining > 0); bitCount++) { control <<= 1; if ((matchLength = FindPattern(sPtr, remaining, ref matchOffset)) != 0) { int length; if (extFmt) { if (matchLength >= 0xFF + 0xF + 3) { length = (matchLength - 0xFF - 0xF - 3); blockBuffer.Add((byte)(0x10 | (length >> 12))); blockBuffer.Add((byte)(length >> 4)); } else if (matchLength >= 0xF + 2) { length = (matchLength - 0xF - 2); blockBuffer.Add((byte)(length >> 4)); } else length = matchLength - 1; } else length = matchLength - 3; control |= 1; blockBuffer.Add((byte)((length << 4) | ((matchOffset - 1) >> 8))); blockBuffer.Add((byte)(matchOffset - 1)); } else { matchLength = 1; blockBuffer.Add(*sPtr); } Consume(sPtr, matchLength, remaining); sPtr += matchLength; remaining -= matchLength; } //Left-align bits control <<= 8 - bitCount; //Write buffer blockBuffer[0] = control; outStream.Write(blockBuffer.ToArray(), 0, blockBuffer.Count); dstLen += blockBuffer.Count; if (progress != null) if ((lastUpdate - remaining) > 0x4000) { lastUpdate = remaining; progress.Update(srcLen - remaining); } } outStream.Flush(); if (progress != null) progress.Finish(); return dstLen; }
public static void Expand(CompressionHeader* header, VoidPtr dstAddress, int dstLen) { Expand(header->Data, dstAddress, dstLen, header->IsExtendedLZ77); }
public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, bool YAZ0) { _pSrc = (byte*)srcAddr; _sourceLen = srcLen; int chunkCount = (int)Math.Ceiling((double)srcLen / _threadChunk); if (progress != null) progress.Begin(0, srcLen, 0); _contractions = new List<Contraction>[chunkCount]; if (YAZ0) { outStream.WriteByte(0x59); outStream.WriteByte(0x61); outStream.WriteByte(0x7A); outStream.WriteByte(0x30); outStream.WriteByte((byte)((_sourceLen >> 24) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 16) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 08) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 00) & 0xFF)); for (int i = 0; i < 8; i++) outStream.WriteByte(0); } else { CompressionHeader header = new CompressionHeader(); header.Algorithm = CompressionType.RunLength; header.ExpandedSize = (int)_sourceLen; outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0)); } ParallelLoopResult result = Parallel.For(0, chunkCount, FindContractions); while (!result.IsCompleted) Thread.Sleep(100); List<Contraction> fullContractions; int codeBits, tempLoc, current; byte codeByte; byte[] temp; int lastUpdate = srcLen; fullContractions = new List<Contraction>(); for (int i = 0; i < _contractions.Length; i++) { fullContractions.AddRange(_contractions[i]); _contractions[i].Clear(); _contractions[i] = null; } _contractions = null; temp = new byte[3 * 8]; codeBits = 0; codeByte = 0; tempLoc = 0; current = 0; for (int i = 0; i < srcLen; ) { if (codeBits == 8) { outStream.WriteByte(codeByte); outStream.Write(temp, 0, tempLoc); codeBits = 0; codeByte = 0; tempLoc = 0; } if (current < fullContractions.Count && fullContractions[current].Location == i) { if (fullContractions[current].Size >= 0x12) { temp[tempLoc++] = (byte)(fullContractions[current].Offset >> 8); temp[tempLoc++] = (byte)(fullContractions[current].Offset & 0xFF); temp[tempLoc++] = (byte)(fullContractions[current].Size - 0x12); } else { temp[tempLoc++] = (byte)((fullContractions[current].Offset >> 8) | ((fullContractions[current].Size - 2) << 4)); temp[tempLoc++] = (byte)(fullContractions[current].Offset & 0xFF); } i += fullContractions[current++].Size; while (current < fullContractions.Count && fullContractions[current].Location < i) current++; } else { codeByte |= (byte)(1 << (7 - codeBits)); temp[tempLoc++] = _pSrc[i++]; } codeBits++; if (progress != null) if (i % 0x4000 == 0) progress.Update(i); } outStream.WriteByte(codeByte); outStream.Write(temp, 0, tempLoc); outStream.Flush(); if (progress != null) progress.Finish(); return (int)outStream.Length; }
public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress) { int dstLen = 4, bitCount; byte control; byte *sPtr = (byte *)srcAddr;//, ceil = sPtr + srcLen; int matchLength, matchOffset = 0; //Initialize Memory.Fill(_First, 0x40000, 0xFF); _wIndex = _wLength = 0; //Write header CompressionHeader header = new CompressionHeader(); header.Algorithm = CompressionType.LZ77; header.ExpandedSize = (int)srcLen; outStream.Write(&header, 4); byte[] blockBuffer = new byte[17]; int dInd; int lastUpdate = srcLen; int remaining = srcLen; if (progress != null) { progress.Begin(0, remaining, 0); } while (remaining > 0) { dInd = 1; //dPtr = blockBuffer + 1; for (bitCount = 0, control = 0; (bitCount < 8) && (remaining > 0); bitCount++) { control <<= 1; if ((matchLength = FindPattern(sPtr, remaining, ref matchOffset)) != 0) { control |= 1; blockBuffer[dInd++] = (byte)(((matchLength - 3) << 4) | ((matchOffset - 1) >> 8)); blockBuffer[dInd++] = (byte)(matchOffset - 1); //*dPtr++ = (byte)(((matchLength - 3) << 4) | ((matchOffset - 1) >> 8)); //*dPtr++ = (byte)(matchOffset - 1); //Consume(sPtr, matchLength); //sPtr += matchLength; } else { matchLength = 1; //Consume(sPtr, 1); blockBuffer[dInd++] = *sPtr; } Consume(sPtr, matchLength, remaining); sPtr += matchLength; remaining -= matchLength; } //Left-align bits control <<= 8 - bitCount; //Write buffer blockBuffer[0] = control; outStream.Write(blockBuffer, 0, dInd); dstLen += dInd; //*blockBuffer = control; //outStream.Write(blockBuffer, (uint)(dPtr - blockBuffer)); //dstLen += (int)(dPtr - blockBuffer); if (progress != null) { if ((lastUpdate - remaining) > 0x4000) { lastUpdate = remaining; progress.Update(srcLen - remaining); } } } //if (progress != null) // progress.Update(srcLen); //while ((dstLen & 3) != 0) //{ // outStream.WriteByte(0); // dstLen++; //} outStream.Flush(); if (progress != null) { progress.Finish(); } return(dstLen); }
public static void Expand(CompressionHeader* header, VoidPtr dstAddress, int dstLen) { }
public int Compress(VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, bool YAZ0) { _pSrc = (byte *)srcAddr; _sourceLen = srcLen; int chunkCount = (int)Math.Ceiling((double)srcLen / _threadChunk); if (progress != null) { progress.Begin(0, srcLen, 0); } _contractions = new List <Contraction> [chunkCount]; if (YAZ0) { outStream.WriteByte(0x59); outStream.WriteByte(0x61); outStream.WriteByte(0x7A); outStream.WriteByte(0x30); outStream.WriteByte((byte)((_sourceLen >> 24) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 16) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 08) & 0xFF)); outStream.WriteByte((byte)((_sourceLen >> 00) & 0xFF)); for (int i = 0; i < 8; i++) { outStream.WriteByte(0); } } else { CompressionHeader header = new CompressionHeader(); header.Algorithm = CompressionType.RunLength; header.ExpandedSize = (int)_sourceLen; outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0)); } ParallelLoopResult result = Parallel.For(0, chunkCount, FindContractions); while (!result.IsCompleted) { Thread.Sleep(100); } List <Contraction> fullContractions; int codeBits, tempLoc, current; byte codeByte; byte[] temp; int lastUpdate = srcLen; fullContractions = new List <Contraction>(); for (int i = 0; i < _contractions.Length; i++) { fullContractions.AddRange(_contractions[i]); _contractions[i].Clear(); _contractions[i] = null; } _contractions = null; temp = new byte[3 * 8]; codeBits = 0; codeByte = 0; tempLoc = 0; current = 0; for (int i = 0; i < srcLen;) { if (codeBits == 8) { outStream.WriteByte(codeByte); outStream.Write(temp, 0, tempLoc); codeBits = 0; codeByte = 0; tempLoc = 0; } if (current < fullContractions.Count && fullContractions[current].Location == i) { if (fullContractions[current].Size >= 0x12) { temp[tempLoc++] = (byte)(fullContractions[current].Offset >> 8); temp[tempLoc++] = (byte)(fullContractions[current].Offset & 0xFF); temp[tempLoc++] = (byte)(fullContractions[current].Size - 0x12); } else { temp[tempLoc++] = (byte)((fullContractions[current].Offset >> 8) | ((fullContractions[current].Size - 2) << 4)); temp[tempLoc++] = (byte)(fullContractions[current].Offset & 0xFF); } i += fullContractions[current++].Size; while (current < fullContractions.Count && fullContractions[current].Location < i) { current++; } } else { codeByte |= (byte)(1 << (7 - codeBits)); temp[tempLoc++] = _pSrc[i++]; } codeBits++; if (progress != null) { if (i % 0x4000 == 0) { progress.Update(i); } } } outStream.WriteByte(codeByte); outStream.Write(temp, 0, tempLoc); outStream.Flush(); if (progress != null) { progress.Finish(); } return((int)outStream.Length); }