Example #1
0
        public static int Decode(byte[] src, int srcpos, byte[] dst, int dstpos, int srclen, bool reverse = false)
        {
            int dstofs = dstpos;

            while (srcpos < srclen)
            {
                int cmd = FastBinaryStream.ReadByte(src, ref srcpos);

                // case 2
                if ((cmd & 0x80) == 0)
                {
                    int count  = ((cmd & 0x70) >> 4) + 3;
                    int relpos = ((cmd & 0x0f) << 8) + FastBinaryStream.ReadByte(src, ref srcpos);
                    if (dstpos + count > dst.Length)
                    {
                        return(dstpos);
                    }
                    ReplicatePrevious(dst, ref dstpos, dstpos - relpos, count);
                }
                // case 1
                else if ((cmd & 0x40) == 0)
                {
                    int count = cmd & 0x3f;
                    if (count == 0)
                    {
                        break;
                    }
                    FastBinaryStream.Copy(src, ref srcpos, dst, ref dstpos, count);
                }
                else
                {
                    cmd &= 0x3f;
                    // case 4
                    if (cmd == 0x3e)
                    {
                        var count = FastBinaryStream.ReadWord(src, ref srcpos);
                        var color = FastBinaryStream.ReadByte(src, ref srcpos);

                        for (int end = dstpos + count; dstpos < end; dstpos++)
                        {
                            dst[dstpos] = color;
                        }
                    }
                    // case 5
                    else if (cmd == 0x3f)
                    {
                        int count  = FastBinaryStream.ReadWord(src, ref srcpos);
                        int cpypos = FastBinaryStream.ReadWord(src, ref srcpos) + dstofs;
                        if (reverse)
                        {
                            cpypos = dstpos - cpypos;
                        }
                        if (cpypos >= dstpos)
                        {
                            throw new IndexOutOfRangeException("cpypos >= dstpos");
                        }

                        for (int end = dstpos + count; dstpos < end; dstpos++)
                        {
                            dst[dstpos] = dst[cpypos++];
                        }
                    }
                    // case 3
                    else
                    {
                        int count  = cmd + 3;
                        int cpypos = FastBinaryStream.ReadWord(src, ref srcpos) + dstofs;
                        if (reverse)
                        {
                            cpypos = dstpos - cpypos;
                        }
                        if (cpypos >= dstpos)
                        {
                            throw new IndexOutOfRangeException("cpypos >= dstpos");
                        }

                        for (int end = dstpos + count; dstpos < end; dstpos++)
                        {
                            dst[dstpos] = dst[cpypos++];
                        }
                    }
                }
            }

            return(dstpos);
        }
Example #2
0
        public static void Decode(byte[] src, int srclen, byte[] dst, byte[] bse)
        {
            int srcpos = 0;
            int dstpos = 0;
            int bsepos = 0;
            int count  = 0;

            while (srcpos < srclen)
            {
                int cmd = FastBinaryStream.ReadByte(src, ref srcpos);

                if ((cmd & 0x80) == 0)
                {
                    // 00000000 c*8 v*8 = xor next c bytes with v
                    if (cmd == 0)
                    {
                        count = FastBinaryStream.ReadByte(src, ref srcpos);
                        byte color = FastBinaryStream.ReadByte(src, ref srcpos);
                        while (count-- > 0)
                        {
                            dst[dstpos++] = (byte)(bse[bsepos++] ^ color);
                        }
                    }
                    // 0ccccccc = xor the next c bytes from source with those in base
                    else
                    {
                        count = cmd;
                        while (count-- > 0)
                        {
                            dst[dstpos++] = (byte)(src[srcpos++] ^ bse[bsepos++]);
                        }
                    }
                }
                else
                {
                    count = cmd & 0x7f;

                    if (count == 0)
                    {
                        count = FastBinaryStream.ReadWord(src, ref srcpos);
                        cmd   = count >> 8;

                        // 10000000 0ccccccc c*8 = large copy base to dest for count
                        if ((cmd & 0x80) == 0)
                        {
                            if (count == 0)
                            {
                                return;
                            }
                            FastBinaryStream.Copy(bse, ref bsepos, dst, ref dstpos, count);
                        }
                        else
                        {
                            count &= 0x3fff;
                            // 10000000 10cccccc c*8 = xor the next c bytes from source with those in base
                            if ((cmd & 0x40) == 0)
                            {
                                while (count-- > 0)
                                {
                                    dst[dstpos++] = (byte)(src[srcpos++] ^ bse[bsepos++]);
                                }
                            }
                            // 10000000 11cccccc c*8 v*8
                            else
                            {
                                byte fill = src[srcpos++];
                                while (count-- > 0)
                                {
                                    dst[dstpos++] = (byte)(bse[bsepos++] ^ fill);
                                }
                            }
                        }
                    }
                    // 1ccccccc = small copy base to dest for count
                    else
                    {
                        FastBinaryStream.Copy(bse, ref bsepos, dst, ref dstpos, count);
                    }
                }
            }
        }