public SpriteDosTransparent(Buffer data, ColorDos[] palette, byte colorOffset = 0)
                : base(data)
            {
                MutableBuffer result = new MutableBuffer(Endian.Endianess.Big);

                while (data.Readable())
                {
                    uint drop = data.Pop <byte>();
                    result.Push(0x00000000u, drop);

                    uint fill = data.Pop <byte>();

                    for (uint i = 0; i < fill; ++i)
                    {
                        uint     palIndex = (uint)(data.Pop <byte>() + colorOffset);
                        ColorDos color    = palette[palIndex];
                        result.Push <byte>(color.B);  // Blue
                        result.Push <byte>(color.G);  // Green
                        result.Push <byte>(color.R);  // Red
                        result.Push <byte>(0xFF);     // Alpha
                    }
                }

                this.data = result.Unfix();
            }
            public SpriteDosMask(Buffer data)
                : base(data)
            {
                MutableBuffer result = new MutableBuffer(Endian.Endianess.Big);

                while (data.Readable())
                {
                    uint drop = data.Pop <byte>();
                    result.Push(0x00000000u, drop);

                    uint fill = data.Pop <byte>();
                    result.Push(0xFFFFFFFFu, fill);
                }

                this.data = result.Unfix();
            }
        public override Buffer Convert()
        {
            uint          resultSize = buffer.Pop <ushort>();
            MutableBuffer result     = new MutableBuffer(Endian.Endianess.Big);

            try
            {
                while (buffer.Readable())
                {
                    uint flag = buffer.Pop <byte>();

                    for (int i = 0; i < 8; ++i)
                    {
                        flag <<= 1;

                        if ((flag & ~0xFF) != 0)
                        {
                            flag &= 0xFF;
                            uint temp        = buffer.Pop <byte>();
                            uint stampSize   = (temp & 0x0F) + 3;
                            uint stampOffset = buffer.Pop <byte>();
                            stampOffset |= ((temp << 4) & 0x0F00);
                            Buffer stamp = result.GetSubBuffer(result.Size - stampOffset, stampSize);
                            result.Push(stamp);
                        }
                        else
                        {
                            result.Push <byte>(buffer.Pop <byte>());
                        }
                    }
                }
            }
            catch
            {
                throw new ExceptionFreeserf(ErrorSystemType.Data, "TPWM source data corrupted");
            }

            if (result.Size != resultSize)
            {
                throw new ExceptionFreeserf(ErrorSystemType.Data, "TPWM source data corrupted");
            }

            return(result);
        }
            public SpriteDosSolid(Buffer data, ColorDos[] palette)
                : base(data)
            {
                uint size = data.Size;

                if (size != (width * height + 10))
                {
                    throw new ExceptionFreeserf(ErrorSystemType.Data, "Failed to extract DOS solid sprite");
                }

                MutableBuffer result = new MutableBuffer(Endian.Endianess.Big);

                while (data.Readable())
                {
                    ColorDos color = palette[data.Pop <byte>()];
                    result.Push <byte>(color.B);  // Blue
                    result.Push <byte>(color.G);  // Green
                    result.Push <byte>(color.R);  // Red
                    result.Push <byte>(0xff);     // Alpha
                }

                this.data = result.Unfix();
            }
            public SpriteDosOverlay(Buffer data, ColorDos[] palette, byte value)
                : base(data)
            {
                MutableBuffer result = new MutableBuffer(Endian.Endianess.Big);

                while (data.Readable())
                {
                    uint drop = data.Pop <byte>();
                    result.Push(0x00000000u, drop);

                    uint fill = data.Pop <byte>();

                    for (uint i = 0; i < fill; ++i)
                    {
                        ColorDos color = palette[value];
                        result.Push <byte>(color.B);  // Blue
                        result.Push <byte>(color.G);  // Green
                        result.Push <byte>(color.R);  // Red
                        result.Push <byte>(value);    // Alpha
                    }
                }

                this.data = result.Unfix();
            }