public SpriteParser(byte[] ChunkData, List <PaletteMap> PMaps, int ChunkID)
        {
            m_ChunkID = ChunkID;

            MemoryStream MemStream = new MemoryStream(ChunkData);
            BinaryReader Reader    = new BinaryReader(MemStream);

            Reader.BaseStream.Position = INDEX_SPRID;
            m_ID = Reader.ReadByte();

            Reader.BaseStream.Position = INDEX_SPRVERSION;
            m_Version = Reader.ReadUInt32();

            if (m_Version != 1000 && m_Version != 1001)
            {
                throw new Exception("Version was: " + m_Version);
            }

            m_FrameCount = Reader.ReadUInt32();

            if (m_Version == 1000)
            {
                m_PaletteID = Reader.ReadUInt32();
            }

            bool PaletteFound = false;

            foreach (PaletteMap Map in PMaps)
            {
                if (Map.ID == m_PaletteID)
                {
                    m_PMap       = Map;
                    PaletteFound = true;
                }
            }

            //This is guesswork, but when the PaletteID is 1, it seems to typically indicate
            //that there's only one palette to choose from...
            if (m_PaletteID == 1)
            {
                m_PMap       = PMaps[0];
                PaletteFound = true;
            }

            if (!PaletteFound)
            {
                throw new Exception("No palette found!");
            }

            for (int i = 0; i < m_FrameCount; i++)
            {
                SpriteFrame Frame = new SpriteFrame();

                Reader.BaseStream.Position = INDEX_SPROFFSETTABLE + 4 * i;
                Reader.BaseStream.Position = Reader.ReadUInt32() + INDEX_SPRVERSION;

                Frame.Width  = Reader.ReadUInt16();
                Frame.Height = Reader.ReadUInt16();
                Frame.Flag   = Reader.ReadUInt16();

                //Zero value skipped.
                Reader.BaseStream.Position += 2;

                Frame.PaletteID = Reader.ReadUInt16();
                Frame.PalMap    = PMaps[0];

                foreach (PaletteMap PMap in PMaps)
                {
                    if (PMap.ID == m_PaletteID)
                    {
                        Frame.PalMap = PMap;
                    }
                }

                Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                Frame.XLocation        = Reader.ReadUInt16();
                Frame.YLocation        = Reader.ReadUInt16();
                Frame.Init();

                EncryptedRowHeader RowHeader = new EncryptedRowHeader();
                int RowID = 0;

                for (int j = 0; j < Frame.Height; j++)
                {
                    long InitPos = Reader.BaseStream.Position;

                    RowHeader = GetDecryptedValues(Reader.ReadUInt16());

                    if (RowHeader.Code == 0)
                    {
                        //byte[] RowSegmentData = Reader.ReadBytes(RowHeader.Count - 2);
                        ReadRowSegment(Reader, RowID, ref Frame);
                        Reader.BaseStream.Position = InitPos + RowHeader.Count;
                        RowID++;
                    }
                    else if (RowHeader.Code == 4)
                    {
                        RowID += RowHeader.Count;
                    }
                    else if (RowHeader.Code == 5)
                    {
                        break;
                    }
                }

                m_Frames.Add(Frame);
            }

            Reader.Close();
        }
        private void DecompressFrame2(ref SpriteFrame Frame, ref BinaryReader Reader)
        {
            bool  quit = false;
            byte  Clr  = 0;
            Color Transparent;
            int   CurrentRow = 0, CurrentColumn = 0;

            byte PixCommand, PixCount = 0;

            if (m_PMap == null)
            {
                m_PMap = new PaletteMap();
            }

            while (quit == false)
            {
                byte RowCommand = Reader.ReadByte();
                byte RowCount   = Reader.ReadByte();

                switch (RowCommand)
                {
                case 0x00:     //Start marker; the count byte is ignored.
                    break;

                //Fill this row with pixel data that directly follows; the count byte of the row command denotes the
                //size in bytes of the row and pixel data.
                case 0x04:
                    RowCount     -= 2;
                    CurrentColumn = 0;

                    while (RowCount > 0)
                    {
                        PixCommand = Reader.ReadByte();
                        PixCount   = Reader.ReadByte();
                        RowCount  -= 2;

                        switch (PixCommand)
                        {
                        case 1:         //Leave the next pixel count pixels as transparent.
                            Transparent = Color.FromArgb(0, 0, 0, 0);
                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);
                            }

                            CurrentColumn += PixCount;

                            break;

                        case 2:         //Fill the next pixel count pixels with a palette color.
                            //The pixel data is two bytes: the first byte denotes the palette color index, and the
                            //second byte is padding (which is always equal to the first byte but is ignored).
                            Clr = Reader.ReadByte();
                            Reader.ReadByte();         //Padding
                            RowCount -= 2;

                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow),
                                                          m_PMap.GetColorAtIndex(Clr));
                            }

                            CurrentColumn += PixCount;

                            break;

                        case 3:         //Set the next pixel count pixels to the palette color indices defined by the
                            //pixel data provided directly after this command.

                            byte Padding = (byte)(PixCount % 2);

                            if (Padding != 0)
                            {
                                RowCount -= (byte)(PixCount + Padding);
                            }
                            else
                            {
                                RowCount -= PixCount;
                            }

                            for (int j = CurrentColumn; j < (CurrentColumn + PixCount); j++)
                            {
                                Clr = Reader.ReadByte();
                                Frame.BitmapData.SetPixel(new Point(j, CurrentRow),
                                                          m_PMap.GetColorAtIndex(Clr));
                            }

                            CurrentColumn += PixCount;

                            if (Padding != 0)
                            {
                                Reader.ReadByte();
                            }

                            break;
                        }
                    }

                    CurrentRow++;

                    break;

                case 0x05:     //End marker. The count byte is always 0, but may be ignored.

                    //Some sprites don't have these, so read them using ReadBytes(), which
                    //simply returns an empty array if the stream couldn't be read.
                    Reader.ReadBytes(2);     //PixCommand and PixCount.

                    quit = true;
                    break;

                case 0x09:     //Leave the next count rows as transparent.
                    PixCommand = Reader.ReadByte();
                    PixCount   = Reader.ReadByte();

                    Transparent = Color.FromArgb(0, 0, 0, 0);

                    for (int i = 0; i < RowCount; i++)
                    {
                        for (int j = CurrentColumn; j < Frame.Width; j++)
                        {
                            Frame.BitmapData.SetPixel(new Point(j, CurrentRow), Transparent);
                        }

                        CurrentRow++;
                    }

                    break;

                case 0x10:     //Start marker, equivalent to 0x00; the count byte is ignored.
                    break;
                }

                if (Reader.BaseStream.Position == Reader.BaseStream.Length)
                {
                    break;
                }
            }
        }
        public SPR2Parser(IffChunk Chunk, List <PaletteMap> PMaps) : base(Chunk)
        {
            m_Name = Name;

            int[]        offsets;
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_Version = Reader.ReadUInt32();

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version == 1000)
            {
                m_ChunkData = Chunk.Data;
            }

            if (m_Version == 1001)
            {
                m_PaletteID  = Reader.ReadUInt32();
                m_FrameCount = Reader.ReadUInt32();
            }
            else
            {
                m_FrameCount = Reader.ReadUInt32();
                m_PaletteID  = Reader.ReadUInt32();
            }

            if (PMaps.Count == 1 && m_PaletteID == 1)
            {
                m_PMap = PMaps[0];
            }
            else
            {
                m_PMap = PMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                {
                                                                    return(true);
                                                                }
                                                                return(false); });
            }

            //Some SPR2s blatantly specify the wrong ID because there's only one palettemap...
            if (m_PMap == null)
            {
                m_PMap = PMaps[0];
            }

            offsets = new int[m_FrameCount];

            if (m_Version == 1000)
            {
                for (int i = 0; i < m_FrameCount; i++)
                {
                    offsets[i] = Reader.ReadInt32();
                    m_FrameOffsets.Add(offsets[i]);
                }
            }

            if (m_Version == 1001)
            {
                for (int l = 0; l < m_FrameCount; l++)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version          = Reader.ReadUInt32();
                    Frame.Size             = Reader.ReadUInt32();
                    Frame.Width            = Reader.ReadUInt16();
                    Frame.Height           = Reader.ReadUInt16();
                    Frame.Flag             = Reader.ReadUInt32();
                    Frame.PaletteID        = Reader.ReadUInt16();
                    Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                    Frame.YLocation        = Reader.ReadUInt16();
                    Frame.XLocation        = Reader.ReadUInt16();

                    if ((SPR2Flags)Frame.Flag == SPR2Flags.HasAlphaChannel)
                    {
                        Frame.Init(true, true);
                    }
                    else
                    {
                        if ((SPR2Flags)Frame.Flag == SPR2Flags.HasZBufferChannel)
                        {
                            Frame.Init(false, true);
                        }
                        else
                        {
                            Frame.Init(false, false);
                        }
                    }

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    if (Frame.HasZBuffer)
                    {
                        Frame.ZBuffer.Unlock(true); //The bitmapdata is locked when the frame is created.
                    }
                    m_Frames.Add(Frame);
                }
            }

            Reader.Close();
        }