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.");
     }
 }
Beispiel #3
0
        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;
        }
Beispiel #8
0
        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)
 {
 }
Beispiel #10
0
        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);
        }