/**<summary>Reads the palette from the graphics data.</summary>*/
        public Palette ReadPalette(BinaryReader reader, long startPosition, int index)
        {
            int        i     = index;
            ImageEntry entry = imageDirectory.entries[i];

            if (entry.Flags.HasFlag(ImageFlags.DirectBitmap))
            {
            }
            else if (entry.Flags.HasFlag(ImageFlags.PaletteEntries))
            {
                Palette palette = new Palette(entry);
                reader.BaseStream.Position = startPosition + entry.StartAddress;

                // Read each color
                for (int j = 0; j < entry.Width; j++)
                {
                    // Yes, the colors are in the order blue, green, red
                    byte blue  = reader.ReadByte();
                    byte green = reader.ReadByte();
                    byte red   = reader.ReadByte();

                    palette.Colors[j] = Color.FromArgb(red, green, blue);
                }
                return(palette);
            }
            return(null);
        }
 /**<summary>Reads the RCT1 image directory.</summary>*/
 public void ReadCSG1(BinaryReader reader)
 {
     while (reader.BaseStream.Position < reader.BaseStream.Length)
     {
         ImageEntry entry = new ImageEntry();
         entry.Read(reader);
         entries.Add(entry);
     }
 }
Ejemplo n.º 3
0
        /**<summary>Reads the image directory.</summary>*/
        public void ReadCSG1(BinaryReader reader)
        {
            //int count = reader.ReadInt32();
            //this.ScanLineLength = reader.ReadInt32();

            //for (int i = 0; i < count; i++) {
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                ImageEntry entry = new ImageEntry();
                entry.Read(reader);
                this.entries.Add(entry);
            }
        }
        //=========== READING ============
        #region Reading

        /**<summary>Reads the image directory.</summary>*/
        public void Read(BinaryReader reader, bool quickLoad = false)
        {
            int count = reader.ReadInt32();

            ScanLineLength = reader.ReadInt32();

            for (int i = 0; i < count; i++)
            {
                ImageEntry entry = new ImageEntry();
                entry.Read(reader);
                if (!quickLoad || i < 168)
                {
                    entries.Add(entry);
                }
            }
        }
        /**<summary>Writes the graphics data.</summary>*/
        public void Write(BinaryWriter writer)
        {
            long startPosition = writer.BaseStream.Position;

            for (int i = 0; i < imageDirectory.NumEntries; i++)
            {
                ImageEntry entry = imageDirectory.entries[i];
                entry.StartAddress = (uint)(writer.BaseStream.Position - startPosition);

                if (entry.Flags.HasFlag(ImageFlags.DirectBitmap))
                {
                    if (!entry.Flags.HasFlag(ImageFlags.CompactedBitmap))
                    {
                        if (entry.Flags.HasFlag(ImageFlags.LandTile))
                        {
                            // Don't know what this flag does, but images can still be written normally.
                        }
                        PaletteImage paletteImage = paletteImages[i];

                        // Write each row
                        for (int y = 0; y < entry.Height; y++)
                        {
                            // Write each pixel in the row
                            for (int x = 0; x < entry.Width; x++)
                            {
                                writer.Write(paletteImage.Pixels[x, y]);
                            }
                        }
                    }
                    else
                    {
                        if (entry.Flags.HasFlag(ImageFlags.LandTile))
                        {
                            // Don't know what this flag does, but images can still be written normally.
                        }
                        PaletteImage paletteImage = paletteImages[i];

                        List <ScanLine> scanLines  = new List <ScanLine>();
                        ushort[]        rowOffsets = new ushort[entry.Height];
                        ushort          rowOffset  = (ushort)(entry.Height * 2);

                        // Write the scan lines in every row and figure out the scan line row offsets
                        for (int y = 0; y < entry.Height; y++)
                        {
                            rowOffsets[y] = rowOffset;

                            ScanLine scanLine = new ScanLine();
                            scanLine.Row = (short)y;

                            // Continue until the next row
                            while ((scanLine.Count & 0x80) == 0x00)
                            {
                                // Reset the scan line count
                                scanLine.Count = 0;

                                // Find each scan line and then check if there's another one in the row
                                bool finishedScanLine = false;
                                bool lastScanLine     = true;
                                for (int x = 0; x + (int)scanLine.Offset < (int)entry.Width; x++)
                                {
                                    if (!finishedScanLine)
                                    {
                                        if (scanLine.Count == 0)
                                        {
                                            // If the scan line hasn't started yet, increment the offset
                                            if (paletteImage.Pixels[x + scanLine.Offset, y] == 0x00)
                                            {
                                                scanLine.Offset++;
                                                x--;
                                            }
                                            else
                                            {
                                                scanLine.Count = 1;
                                            }
                                        }
                                        else if (paletteImage.Pixels[x + scanLine.Offset, y] == 0x00 || x == 0x7F)
                                        {
                                            // If the next pixel is transparent or the scan line is as big as possible, finish the line
                                            finishedScanLine = true;
                                        }
                                        else
                                        {
                                            // Increment the scan line byte count
                                            scanLine.Count++;
                                        }
                                    }
                                    else if (paletteImage.Pixels[x + scanLine.Offset, y] != 0x00)
                                    {
                                        // There is another scan line after this
                                        lastScanLine = false;
                                        break;
                                    }
                                }
                                // Set the end flag if the scan line is the last in the row
                                if (lastScanLine)
                                {
                                    scanLine.Count |= 0x80;
                                }
                                // If the row has all transparent pixels, set the offset to 0
                                if (scanLine.Count == 0)
                                {
                                    scanLine.Offset = 0;
                                    scanLine.Count  = 0;
                                }

                                rowOffset += (ushort)(2 + (scanLine.Count & 0x7F));
                                scanLines.Add(scanLine);

                                // Increment the scan line count
                                if (!lastScanLine)
                                {
                                    scanLine.Offset += (byte)(scanLine.Count & 0x7F);
                                }
                            }
                        }

                        // Write the row offsets
                        for (int j = 0; j < entry.Height; j++)
                        {
                            writer.Write(rowOffsets[j]);
                        }

                        // Write the scan lines
                        for (int j = 0; j < scanLines.Count; j++)
                        {
                            writer.Write(scanLines[j].Count);
                            writer.Write(scanLines[j].Offset);
                            for (int k = 0; k < (scanLines[j].Count & 0x7F); k++)
                            {
                                try {
                                    writer.Write(paletteImage.Pixels[k + scanLines[j].Offset, scanLines[j].Row]);
                                }
                                catch (Exception) {
                                }
                            }
                        }
                    }
                }
                else if (entry.Flags.HasFlag(ImageFlags.PaletteEntries))
                {
                    Palette palette = palettes[i];

                    // Write each color
                    for (int j = 0; j < entry.Width; j++)
                    {
                        // Yes, the colors are in the order blue, green, red
                        writer.Write(palette.Colors[j].B);
                        writer.Write(palette.Colors[j].G);
                        writer.Write(palette.Colors[j].R);
                    }
                }
            }
        }
        /**<summary>Reads the graphics data.</summary>*/
        public void Read(BinaryReader reader)
        {
            long startPosition = reader.BaseStream.Position;

            for (int i = 0; i < imageDirectory.NumEntries; i++)
            {
                ImageEntry entry = imageDirectory.entries[i];
                if (entry.Flags.HasFlag(ImageFlags.DirectBitmap))
                {
                    if (!entry.Flags.HasFlag(ImageFlags.CompactedBitmap))
                    {
                        if (entry.Flags.HasFlag(ImageFlags.LandTile))
                        {
                            // Don't know what this flag does, but images can still be read normally.
                        }
                        PaletteImage paletteImage = new PaletteImage(entry);
                        reader.BaseStream.Position = startPosition + entry.StartAddress;

                        // Read each row
                        for (int y = 0; y < entry.Height; y++)
                        {
                            for (int x = 0; x < entry.Width; x++)
                            {
                                byte b = reader.ReadByte();
                                paletteImage.Pixels[x, y] = b;
                            }
                        }
                        paletteImages.Add(paletteImage);
                        palettes.Add(null);
                        numImages++;
                    }
                    else
                    {
                        if (entry.Flags.HasFlag(ImageFlags.LandTile))
                        {
                            // Don't know what this flag does, but images can still be read normally.
                        }
                        PaletteImage paletteImage = new PaletteImage(entry);
                        uint[]       rowOffsets   = new uint[entry.Height];
                        reader.BaseStream.Position = startPosition + entry.StartAddress;

                        // Read the row offsets
                        for (int j = 0; j < entry.Height; j++)
                        {
                            rowOffsets[j] = reader.ReadUInt16();
                        }

                        // Read the scan lines in each row
                        for (int j = 0; j < entry.Height; j++)
                        {
                            reader.BaseStream.Position = startPosition + entry.StartAddress + rowOffsets[j];
                            byte b1 = 0;
                            byte b2 = 0;

                            // A MSB of 1 means the last scan line in a row
                            while ((b1 & 0x80) == 0)
                            {
                                // Read the number of bytes of data
                                b1 = reader.ReadByte();
                                // Read the offset from the left edge of the image
                                b2 = reader.ReadByte();
                                for (int k = 0; k < (b1 & 0x7F); k++)
                                {
                                    byte b3 = reader.ReadByte();
                                    paletteImage.Pixels[b2 + k, j] = b3;
                                }
                            }
                        }
                        paletteImages.Add(paletteImage);
                        palettes.Add(null);
                        numImages++;
                    }
                }
                else if (entry.Flags.HasFlag(ImageFlags.PaletteEntries))
                {
                    Palette palette = new Palette(entry);
                    reader.BaseStream.Position = startPosition + entry.StartAddress;

                    // Read each color
                    for (int j = 0; j < entry.Width; j++)
                    {
                        // Yes, the colors are in the order blue, green, red
                        byte blue  = reader.ReadByte();
                        byte green = reader.ReadByte();
                        byte red   = reader.ReadByte();

                        palette.Colors[j] = Color.FromArgb(red, green, blue);
                    }
                    paletteImages.Add(null);
                    palettes.Add(palette);
                    numPalettes++;
                }
            }
        }
        /**<summary>Reads the palette image from the graphics data.</summary>*/
        public PaletteImage ReadPaletteImage(BinaryReader reader, long startPosition, int index)
        {
            int        i     = index;
            ImageEntry entry = imageDirectory.entries[i];

            if (entry.Flags.HasFlag(ImageFlags.DirectBitmap))
            {
                if (!entry.Flags.HasFlag(ImageFlags.CompactedBitmap))
                {
                    if (entry.Flags.HasFlag(ImageFlags.LandTile))
                    {
                        // Don't know what this flag does, but images can still be read normally.
                    }
                    PaletteImage paletteImage = new PaletteImage(entry);
                    reader.BaseStream.Position = startPosition + entry.StartAddress;

                    // Read each row
                    for (int y = 0; y < entry.Height; y++)
                    {
                        for (int x = 0; x < entry.Width; x++)
                        {
                            byte b = reader.ReadByte();
                            paletteImage.Pixels[x, y] = b;
                        }
                    }
                    return(paletteImage);
                }
                else
                {
                    if (entry.Flags.HasFlag(ImageFlags.LandTile))
                    {
                        // Don't know what this flag does, but images can still be read normally.
                    }
                    PaletteImage paletteImage = new PaletteImage(entry);
                    uint[]       rowOffsets   = new uint[entry.Height];
                    reader.BaseStream.Position = startPosition + entry.StartAddress;

                    // Read the row offsets
                    for (int j = 0; j < entry.Height; j++)
                    {
                        rowOffsets[j] = reader.ReadUInt16();
                    }

                    // Read the scan lines in each row
                    for (int j = 0; j < entry.Height; j++)
                    {
                        reader.BaseStream.Position = startPosition + entry.StartAddress + rowOffsets[j];
                        byte b1 = 0;
                        byte b2 = 0;

                        // A MSB of 1 means the last scan line in a row
                        while ((b1 & 0x80) == 0)
                        {
                            // Read the number of bytes of data
                            b1 = reader.ReadByte();
                            // Read the offset from the left edge of the image
                            b2 = reader.ReadByte();
                            for (int k = 0; k < (b1 & 0x7F); k++)
                            {
                                byte b3 = reader.ReadByte();
                                paletteImage.Pixels[b2 + k, j] = b3;
                            }
                        }
                    }
                    return(paletteImage);
                }
            }
            else if (entry.Flags.HasFlag(ImageFlags.PaletteEntries))
            {
            }
            return(null);
        }