// 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); }
// 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); }
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; } }