// As found in .DAT archives (RESOURCE.DAT, IO.DAT)
        public void Load(string destinationDirectory, string baseName, BinaryReader binaryReader)
        {
            xOffset = binaryReader.ReadInt16();
            yOffset = binaryReader.ReadInt16();
            binaryReader.BaseStream.Seek(4, SeekOrigin.Current);
            width = binaryReader.ReadUInt16();
            height = binaryReader.ReadUInt16();
            binaryReader.BaseStream.Seek(2, SeekOrigin.Current);
            uint length = binaryReader.ReadUInt32();

            var imageOffset = binaryReader.BaseStream.Position;

            var rowDataOffsets = new ushort[height];
            for (int i = 0; i < height; ++i) {
                rowDataOffsets[i] = binaryReader.ReadUInt16();
            }

            var bmp = new Bmp(width, height);
            var imageData = binaryReader.ReadBytes((int)length - 2*height);

            ReadImage(imageData, rowDataOffsets, false, bmp.Data);

            Debug.Assert(binaryReader.BaseStream.Position - imageOffset == length);
            bmp.Save(Path.Combine(destinationDirectory, baseName), ImageFormat);
            Bmp.SaveOffsets(baseName, xOffset, yOffset);
        }
        public void Load(string destinationDirectory, string resourceName, BinaryReader binaryReader)
        {
            binaryReader.BaseStream.Seek(2, SeekOrigin.Current);
            uint length = binaryReader.ReadUInt32();
            byte[] imageData = binaryReader.ReadBytes((int)length);
            short xOffset = binaryReader.ReadInt16();
            short yOffset = binaryReader.ReadInt16();
            ushort width = binaryReader.ReadUInt16();
            ushort height = binaryReader.ReadUInt16();
            binaryReader.BaseStream.Seek(8, SeekOrigin.Current);

            var bmp = new Bmp(width, height);
            var colorData = bmp.Data;
            var palette = PaletteLoader.DefaultPalette;
            int index = 0;
            for (int y = 0; y < height; ++y) {
                for (int x = 0; x < width; ++x) {
                    colorData[y, x] = palette.Colors[imageData[index]];
                    ++index;
                }
            }

            bmp.Save(Path.Combine(destinationDirectory, resourceName), ImageFormat);
            Bmp.SaveOffsets(resourceName, xOffset, yOffset);
        }
        public void Load(string destinationDirectory, string resourceName, BinaryReader binaryReader)
        {
            short xOffset = binaryReader.ReadInt16();
            short yOffset = binaryReader.ReadInt16();
            binaryReader.BaseStream.Seek(4, SeekOrigin.Current);
            ushort width = binaryReader.ReadUInt16();
            ushort height = binaryReader.ReadUInt16();
            binaryReader.BaseStream.Seek(2, SeekOrigin.Current);
            uint length = binaryReader.ReadUInt32();
            var start = binaryReader.BaseStream.Position;

            // Set to magenta for now (should be white ("gray" as RTTR calls it))
            var gray = new Rgba {
                R = byte.MaxValue,
                G = 0,//byte.MaxValue,
                B = byte.MaxValue,
                A = byte.MaxValue
            };
            var transparent = new Rgba {
                R = byte.MaxValue,
                G = byte.MaxValue,
                B = byte.MaxValue,
                A = 0
            };

            // Skip row indexes, not necessary
            binaryReader.BaseStream.Seek(2 * height, SeekOrigin.Current);
            var bmp = new Bmp(width, height);
            var palette = PaletteLoader.DefaultPalette;

            for (int y = 0; y < height; ++y) {
                int x = 0;
                while (x < width) {
                    byte count = binaryReader.ReadByte();
                    for (int i = 0; i < count; ++i) {
                        bmp.Data[y, x] = gray;
                        ++x;
                    }
                    count = binaryReader.ReadByte();
                    for (int i = 0; i < count; ++i) {
                        bmp.Data[y, x] = transparent;
                        ++x;
                    }
                }
                // Skip delimiter
                binaryReader.ReadByte();
            }

            binaryReader.BaseStream.Seek(start + length, SeekOrigin.Begin);
            bmp.Save(Path.Combine(destinationDirectory, resourceName), ImageFormat.Png);
            Bmp.SaveOffsets(resourceName, xOffset, yOffset);
        }
        public void Load(string destinationDirectory, string resourceName, BinaryReader binaryReader)
        {
            short xOffset = binaryReader.ReadInt16();
            short yOffset = binaryReader.ReadInt16();
            binaryReader.BaseStream.Seek(4, SeekOrigin.Current);
            ushort width = binaryReader.ReadUInt16();
            ushort height = binaryReader.ReadUInt16();
            binaryReader.BaseStream.Seek(2, SeekOrigin.Current);
            uint length = binaryReader.ReadUInt32();
            var start = binaryReader.BaseStream.Position;

            if (length <= 0) {
                return;
            }

            binaryReader.BaseStream.Seek(2 * height, SeekOrigin.Current);
            var bmp = new Bmp(width, height);
            var colorData = bmp.Data;
            var palette = PaletteLoader.DefaultPalette;

            for (int y = 0; y < height; ++y) {
                int x = 0;
                while (x < width) {
                    // color pixels
                    byte count = binaryReader.ReadByte();
                    for (int i = 0; i < count; ++i) {
                        colorData[y, x] = palette.Colors[binaryReader.ReadByte()];
                        ++x;
                    }
                    // transparent pixels
                    count = binaryReader.ReadByte();
                    for (int i = 0; i < count; ++i) {
                        colorData[y, x] = new Rgba { A = 0 };
                        ++x;
                    }
                }
                // skip delimiter
                binaryReader.ReadByte();
            }
            // Make sure stream continues right after this format's data
            binaryReader.BaseStream.Seek(start + length, SeekOrigin.Begin);

            bmp.Save(Path.Combine(destinationDirectory, resourceName), ImageFormat);
            Bmp.SaveOffsets(resourceName, xOffset, yOffset);
        }
        // As found in .BOB archives
        public void Load(byte[] imageData, string destinationDirectory, string baseName, BinaryReader binaryReader)
        {
            ushort id = binaryReader.BE_ReadUInt16();
            if (id != 0xF401) {
                throw new Exception(baseName + " is an invalid PlayerBitmap");
            }

            width = 32;
            height = binaryReader.ReadByte();
            var rowDataOffsets = new ushort[height];
            for (int i = 0; i < height; ++i) {
                rowDataOffsets[i] = binaryReader.ReadUInt16();
            }
            xOffset = 16;
            yOffset = binaryReader.ReadByte();

            var bmp = new Bmp(width, height);
            ReadImage(imageData, rowDataOffsets, true, bmp.Data);

            bmp.Save(Path.Combine(destinationDirectory, baseName), ImageFormat);
            Bmp.SaveOffsets(baseName, xOffset, yOffset);
        }
Example #6
0
        // Tentative to decrypt the DATA/TEXTURE/GOU*.DAT files, which look like 256x256 paletted textures
        public void Load(string sourceFileName, string destinationDirectory)
        {
            using (var binaryReader = new BinaryReader(File.Open(sourceFileName, FileMode.Open))) {
                if (binaryReader.BaseStream.Length != 65536) {
                    throw new Exception(sourceFileName + " is an invalid texture");
                }

                var palette = PaletteLoader.DefaultPalette;
                var bmp = new Bmp(256, 256);
                var colorData = bmp.Data;

                for (int y = 0; y < 256; ++y) {
                    for (int x = 0; x < 256; ++x) {
                        colorData[y, x] = palette.Colors[binaryReader.ReadByte()];
                    }
                }

                Debug.Assert(binaryReader.BaseStream.Position == binaryReader.BaseStream.Length);
                var destinationFileName = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(sourceFileName));
                bmp.Save(destinationFileName, ImageFormat.Png);
            }
        }
        // Used for loading .BOB archives. Quite a horrible method signature if you ask me!
        public void Load(ushort width, ushort height, short xOffset, short yOffset, byte[] imageData, ushort[] rowDataOffsets, string destinationDirectory, string baseName)
        {
            this.width = width;
            this.height = height;
            this.xOffset = xOffset;
            this.yOffset = yOffset;

            var bmp = new Bmp(width, height);
            ReadImage(imageData, rowDataOffsets, true, bmp.Data);

            bmp.Save(Path.Combine(destinationDirectory, baseName), ImageFormat);
            Bmp.SaveOffsets(baseName, xOffset, yOffset);
        }
Example #8
0
        bool readChunk(BinaryReader binaryReader)
        {
            var id = new string(binaryReader.ReadChars(4));
            uint length = binaryReader.BE_ReadUInt32();
            if (length % 2 != 0) {
                ++length;
            }

            switch (id) {
                case "BMHD":
                    width = binaryReader.BE_ReadUInt16();
                    height = binaryReader.BE_ReadUInt16();
                    binaryReader.BaseStream.Seek(4, SeekOrigin.Current);
                    colorDepth = binaryReader.ReadUInt16();
                    compression = binaryReader.ReadUInt16();
                    binaryReader.BaseStream.Seek(length - 12, SeekOrigin.Current); // Skip remaining bytes of this chunk

                    bmp = new Bmp(width, height);
                    return false;
                case "CMAP":
                    if (length != 768) {
                        throw new Exception("Invalid color palette in " + lbmName);
                    }
                    for (int i = 0; i < 256; ++i) {
                        palette[i] = new Rgba {
                            R = binaryReader.ReadByte(),
                            G = binaryReader.ReadByte(),
                            B = binaryReader.ReadByte(),
                            A = byte.MaxValue
                        };
                    }
                    return false;
                case "BODY":
                    if (compression != 1) {
                        throw new Exception("OMG WTF?!");
                    }
                    int numPixels = 0;
                    bool compressed = false;
                    byte compressedIndex = 0;

                    for (int y = 0; y < height; ++y) {
                        for (int x = 0; x < width; ++x) {

                            if (numPixels == 0) {
                                byte indicator = binaryReader.ReadByte();
                                compressed = indicator > 128;
                                if (compressed) {
                                    numPixels = 255 - indicator + 2;
                                    compressedIndex = binaryReader.ReadByte();
                                }
                                else {
                                    numPixels = indicator + 1;
                                }
                            }
                            var index = compressed ? compressedIndex : binaryReader.ReadByte();
                            bmp.Data[y, x] = palette[index];
                            --numPixels;
                        }
                    }
                    return true;
                default:
                    binaryReader.BaseStream.Seek(length, SeekOrigin.Current);
                    return false;
            }
        }