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(BinaryReader binaryReader) { binaryReader.BaseStream.Seek(2, SeekOrigin.Current); var rgba = new Rgba[256]; for (int i = 0; i < rgba.Length; ++i) { rgba[i] = new Rgba { R = binaryReader.ReadByte(), G = binaryReader.ReadByte(), B = binaryReader.ReadByte() }; } Palettes.Add(new Palette(rgba)); }
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); }
public void Load(string sourceFileName) { if (new FileInfo(sourceFileName).Length != 768) { throw new InvalidDataException(); } var colors = new Rgba[256]; using (var binaryReader = new BinaryReader(File.Open(sourceFileName, FileMode.Open))) { for (int i = 0; i < 256; ++i) { colors[i] = new Rgba { R = binaryReader.ReadByte(), G = binaryReader.ReadByte(), B = binaryReader.ReadByte(), A = byte.MaxValue }; } } PaletteLoader.Palettes.Add(new Palette(colors)); }
public void Load(string fileName) { using (var binaryReader = new BinaryReader(File.Open(fileName, FileMode.Open))) { var form = new string(binaryReader.ReadChars(4)); if (form != "FORM") { throw new InvalidDataException(); } uint fileLength = binaryReader.ReadUInt32(); var PBM_ = new string(binaryReader.ReadChars(4)); if (PBM_ != "PBM ") { throw new InvalidDataException(); } while (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { var id = new string(binaryReader.ReadChars(4)); uint chunkLength = binaryReader.BE_ReadUInt32(); if (chunkLength % 2 != 0) { ++chunkLength; } byte[] chunk = binaryReader.ReadBytes((int)chunkLength); if (id == "CMAP" && chunkLength == 256 * 3) { var rgba = new Rgba[256]; for (int i = 0; i < 256; ++i) { rgba[i] = new Rgba { R = chunk[3 * i], G = chunk[3 * i + 1], B = chunk[3 * i + 2], A = byte.MaxValue }; } var newPalette = new Palette(rgba); PaletteLoader.Palettes.Add(newPalette); if (Path.GetFileNameWithoutExtension(fileName) == "PAL5") { PaletteLoader.DefaultPalette = newPalette; } } } } }
void ReadImage(byte[] imageData, ushort[] rowDataOffsets, bool absoluteOffsets, Rgba[,] colorData) { var palette = PaletteLoader.DefaultPalette; int position = 0; for (int y = 0; y < height; ++y) { position = rowDataOffsets[y] - (absoluteOffsets ? 0 : 2 * height); ushort x = 0; while (x < width) { byte shift = imageData[position++]; if (shift < 0x40) { for (byte i = 0; i < shift; ++i) { // Set to transparent colorData[y, x].A = 0; ++x; } } else if (shift < 0x80) { shift -= 0x40; for (byte i = 0; i < shift; ++i) { // Set to corresponding color in palette var color = palette.Colors[imageData[position++]]; colorData[y, x] = color; ++x; } } else if (shift < 0xC0) { shift -= 0x80; byte transparency = imageData[position++]; // libsiedler2 uses this for tex_pdata. I don't know what purpose does that serve. for (byte i = 0; i < shift; ++i) { // TEST: hardcode a visible color here colorData[y, x] = new Rgba { A = (byte)(byte.MaxValue - 64 * transparency), R = 255, B = 0, G = 0 }; ++x; } } else { shift -= 0xC0; var color = palette.Colors[imageData[position++]]; for (byte i = 0; i < shift; ++i) { colorData[y, x] = color; ++x; } } } } }
public Bmp(int width, int height) { Width = width; Height = height; Data = new Rgba[height, width]; }
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; } }
public Palette(Rgba[] rgba) { Colors = rgba; }