Ejemplo n.º 1
0
        public static byte[] decode(byte[] src)
        {
            if (!IsYaz0(src))
            {
                return(src);
            }

            uint decompressedSize = EndianBytesOperator.readUInt(src, 0x04);

            byte[] dst    = new byte[decompressedSize];
            uint   srcPos = 0x10;
            uint   dstPos = 0;

            byte Opcode = 0x00;
            List <KeyValuePair <int, KeyValuePair <int, int> > > finds = new List <KeyValuePair <int, KeyValuePair <int, int> > >();

            while (true)
            {
                Opcode = src[srcPos];
                srcPos++;
                for (int i = 0; i < 8; i++, Opcode <<= 1)
                {
                    if ((Opcode & 0x80) != 0)
                    {
                        dst[dstPos] = src[srcPos];
                        dstPos++;
                        srcPos++;
                    }
                    else
                    {
                        byte b1 = src[srcPos];
                        byte b2 = src[srcPos + 1];
                        srcPos += 2;

                        uint copyLen = 0;
                        if ((b1 >> 4) == 0)
                        {
                            copyLen = (uint)src[srcPos] + 0x12;
                            srcPos++;
                        }
                        else
                        {
                            copyLen = (uint)(b1 >> 4) + 0x02;
                        }
                        uint dist    = (uint)((b1 & 0x0F) << 8 | b2) + 1;
                        uint copyPos = dstPos - dist;
                        finds.Add(new KeyValuePair <int, KeyValuePair <int, int> >((int)dstPos, new KeyValuePair <int, int>((int)copyPos, (int)copyLen)));
                        for (int j = 0; j < copyLen; j++)
                        {
                            dst[dstPos] = dst[copyPos];
                            dstPos++;
                            copyPos++;
                        }
                    }

                    if (dstPos >= decompressedSize)
                    {
                        return(dst);
                    }
                }
            }
        }
Ejemplo n.º 2
0
 public static bool IsYaz0(byte[] bytes)
 {
     return(EndianBytesOperator.readString(bytes, 0, 4) == "Yaz0");
 }
Ejemplo n.º 3
0
        public static byte[] encode(byte[] src)
        {
            //find need compressed position
            uint curPos = 0;
            uint endPos = (uint)src.Length;
            List <KeyValuePair <uint, KeyValuePair <uint, uint> > > finds = new List <KeyValuePair <uint, KeyValuePair <uint, uint> > >();

            while (curPos + 0x03 <= endPos)
            {
                var find = searchNextNCPoses(src, curPos, endPos);
                if (find[0].Value.Value != 0)
                {
                    finds.AddRange(find);
                }
                curPos = find[find.Count - 1].Key + find[find.Count - 1].Value.Value;
            }

            //compress
            byte[] temp      = new byte[src.Length + src.Length / 8];
            uint   writeLen  = 0;
            uint   srcPos    = 0;
            uint   dstPos    = 0x01;
            uint   opcodePos = 0;
            uint   cycle     = 0x00;

            foreach (var find in finds)
            {
                //write data that does not need to be compressed
                while (srcPos < find.Key)
                {
                    if (cycle == 8)
                    {
                        opcodePos = dstPos;
                        dstPos++;
                        cycle = 0x00;
                    }
                    temp[opcodePos] = (byte)(temp[opcodePos] | 0x80 >> (int)cycle);
                    cycle++;

                    temp[dstPos] = src[srcPos];
                    dstPos++;
                    srcPos++;
                }

                //write data that need to compressed
                if (cycle == 8)
                {
                    opcodePos = dstPos;
                    dstPos++;
                    cycle = 0x00;
                }
                cycle++;

                uint findLen = find.Value.Value;
                uint findPos = find.Value.Key;
                uint pos     = find.Key;
                uint dist    = pos - findPos - 1;
                if (findLen < 0x12)
                {
                    byte b1 = (byte)((findLen - 2) << 4 | dist >> 8);
                    byte b2 = (byte)(dist & 0xFF);

                    temp[dstPos]     = b1;
                    temp[dstPos + 1] = b2;
                    dstPos          += 2;
                }
                else
                {
                    byte b1 = (byte)(dist >> 8);
                    byte b2 = (byte)(dist & 0xFF);
                    byte b3 = (byte)(findLen - 0x12);

                    temp[dstPos]     = b1;
                    temp[dstPos + 1] = b2;
                    temp[dstPos + 2] = b3;
                    dstPos          += 3;
                }

                srcPos += findLen;
            }

            //write data that does not need to be compressed
            while (srcPos < src.Length)
            {
                if (cycle == 8)
                {
                    opcodePos = dstPos;
                    dstPos++;
                    cycle = 0x00;
                }
                temp[opcodePos] = (byte)(temp[opcodePos] | 0x80 >> (int)cycle);
                cycle++;

                temp[dstPos] = src[srcPos];
                dstPos++;
                srcPos++;
            }

            writeLen = dstPos;

            byte[] ret = new byte[writeLen + 0x10];
            EndianBytesOperator.writeString(ret, 0, "Yaz0", 4);
            EndianBytesOperator.writeUInt(ret, 0x04, (uint)src.Length);
            for (int i = 0; i < writeLen; i++)
            {
                ret[i + 0x10] = temp[i];
            }

            return(ret);
        }