public void ImportImageDataAs15Bit(Bitmap bitmap) { if (bitmap == null) { return; } BitsPerPixel = 16; FirstByte = 1; ImageWidth = bitmap.Width; ImageHeight = bitmap.Height; ImageOffset = default; FrameWidth = (byte)bitmap.Width; FrameHeight = (byte)bitmap.Height; ImageHandle = 1; PaletteHandle = 1; Memory = 1; PaletteHandle2 = 1; ImageData = new byte[bitmap.Width * bitmap.Height * 2]; for (int x = 0; x < ImageWidth; x++) { for (int y = 0; y < ImageHeight; y++) { Color pixel = bitmap.GetPixel(x, y); ushort data16 = Palette_15Bit.ConvertColor(pixel); int pos = (x + y * ImageWidth) * 2; byte[] b = BitConverter.GetBytes(data16); ImageData[pos] = b[0]; ImageData[pos + 1] = b[1]; } } }
public void Write(BinaryWriter writer, ref Palette_15Bit prevPalette) { if (PaletteType == PaletteType.EMPTY_ENTRY) { // no data. Wirte a single null byte. writer.Write('\0'); return; } if (PaletteHandle == 0) { // base palette or high color (16-bit). Any non-zero value permitted. Fix this to 1 FirstByte = 1; } else if (prevPalette.Equals(Palette)) { FirstByte = 2; } else { FirstByte = 1; prevPalette = Palette; // for the next entry } writer.Write(FirstByte); writer.Write(ImageWidth); writer.Write(ImageHeight); writer.Write(ImageOffsetX); writer.Write(ImageOffsetY); writer.Write(ImageHandle); writer.Write(PaletteHandle); writer.Write(BitsPerPixel); writer.Write(FrameHeight); writer.Write(FrameWidth); writer.Write(Alignment); writer.Write(ImageData); if (PaletteType == PaletteType.EMBEDDED_PALETTE) { if (Memory == 0) { Memory = 1; } if (PaletteHandle2 == 0) { PaletteHandle2 = 1; } writer.Write(Memory); writer.Write(PaletteHandle2); Palette.Write(writer); } }
public void WriteToFile(string destinationPath) { using (FileStream fs = new FileStream(destinationPath, FileMode.Create)) { Palette_15Bit currentPalette = new Palette_15Bit(); using (BinaryWriter writer = new BinaryWriter(fs)) { foreach (ResourceElement rex in Resources) { rex.Write(writer, ref currentPalette); } } } }
private void Resize() { int h = _houses; int sets = (h - 1) / 16 + 1; if (_palettes == null || sets > _palettes.Length) { Palette_15Bit[] list = new Palette_15Bit[sets]; for (int i = 0; i < list.Length; i++) { list[i] = new Palette_15Bit(); } _palettes?.CopyTo(list, 0); _palettes = list; } }
public void ReadFromFile(string filePath) { Resources.Clear(); using (FileStream fs = new FileStream(filePath, FileMode.Open)) { using (BinaryReader reader = new BinaryReader(fs)) { Palette_15Bit currentPalette = new Palette_15Bit(); while (fs.Position < fs.Length) { long p = fs.Position; ResourceElement rex = new ResourceElement(); rex.Read(reader, ref currentPalette); Resources.Add(rex); } } } }
private void bPrevNext_Click(object sender, EventArgs e) { if (_currPalette + 1 >= _pals.Length) { if (MessageBox.Show("A new palette page will be created to support houses above this index. This will increase the size of the file. Proceed?", "Dune 2000 Editor", MessageBoxButtons.OKCancel) == DialogResult.OK) { Palette_15Bit[] palnew = new Palette_15Bit[_pals.Length + 1]; _pals.CopyTo(palnew, 0); palnew[_pals.Length] = new Palette_15Bit(); _pals = palnew; } else { return; } } _currPalette++; RedrawPalette(); }
public void Export(Palette_18Bit basePalette, int key, ResourceElement element, string rootDir, string imagePath, string palettePath, IProgress <int> progress = null) { if (element.PaletteType == PaletteType.EMPTY_ENTRY) { return; } ResourceExportEntry expentry = new ResourceExportEntry(); expentry.FrameSize = element.FrameSize; expentry.ImageOffset = element.ImageOffset; expentry.Alignment = element.Alignment; expentry.ImageHandle = element.ImageHandle; expentry.PaletteHandle = element.PaletteHandle; expentry.UsePalette = element.BitsPerPixel == 8; if (expentry.UsePalette) { expentry.UseOwnPalette = element.PaletteHandle != 0; } else { expentry.UseOwnPalette = null; } HousePaletteFile dummy = new HousePaletteFile(); // modify palette to remove unique colors. Palette_15Bit opal = element.Palette?.Clone(); if (element.Palette != null) { element.Palette.MakeSpecialIndicesUnique(out _); } Bitmap image = element.GetBitmap(basePalette, dummy, false, false, -1); if (!Path.IsPathRooted(imagePath)) { imagePath = Path.Combine(rootDir, imagePath); } Directory.CreateDirectory(Path.GetDirectoryName(imagePath)); image.Save(imagePath); expentry.ImagePath = WinAPI.GetRelativePath(rootDir + @"\", imagePath); if (expentry.UseOwnPalette ?? false) { PaletteFile palfile = new PaletteFile(); palfile.Palette.Import(element.Palette); if (!Path.IsPathRooted(palettePath)) { palettePath = Path.Combine(rootDir, palettePath); } Directory.CreateDirectory(Path.GetDirectoryName(palettePath)); palfile.WriteToFile(palettePath); expentry.PalettePath = WinAPI.GetRelativePath(rootDir + @"\", palettePath); } // restore the original palette element.Palette = opal; Entries.Put(key.ToString(), expentry); progress?.Report(key); }
public Bitmap GetBitmap(Palette_18Bit basePalette, HousePaletteFile housePalette, bool includeFrame, bool makeTransparent, int houseIndex) { if (PaletteType == PaletteType.EMPTY_ENTRY) { // at least draw something so it does not error out. Bitmap empty = new Bitmap(1, 1); empty.MakeTransparent(); return(empty); } Bitmap bmp = new Bitmap(ImageWidth, ImageHeight); if (BitsPerPixel == 8) { IPalette pal = (PaletteHandle == 0) ? (IPalette)basePalette.Clone() : Palette.Clone(); if (houseIndex != -1) { pal = housePalette.Merge(pal, houseIndex); } for (int x = 0; x < ImageWidth; x++) { for (int y = 0; y < ImageHeight; y++) { int pos = x + y * ImageWidth; byte data8 = ImageData[pos]; if (makeTransparent && data8 == 0) { bmp.SetPixel(x, y, Color.Transparent); } else if (makeTransparent && data8 == 1) { bmp.SetPixel(x, y, Color.FromArgb(128, 0, 0, 0)); } else { bmp.SetPixel(x, y, pal.Get(data8)); } } } } else if (BitsPerPixel == 16) { // doesn't care about palettes, as its image data is direct color for (int x = 0; x < ImageWidth; x++) { for (int y = 0; y < ImageHeight; y++) { int pos = (x + y * ImageWidth) * 2; ushort data16 = BitConverter.ToUInt16(ImageData, pos); bmp.SetPixel(x, y, Palette_15Bit.ConvertColor(data16)); } } } else { throw new InvalidDataException("Unexpected bits per pixel! (Value = {0})".F(BitsPerPixel)); } if (makeTransparent) { bmp.MakeTransparent(Palette.Get(0)); } if (includeFrame) { Bitmap bmpFrame = new Bitmap(FrameWidth, FrameHeight); bmpFrame.MakeTransparent(); Graphics g = Graphics.FromImage(bmpFrame); g.DrawImageUnscaled(bmp, new Point((FrameWidth - ImageWidth) / 2, (FrameHeight - ImageHeight) / 2)); return(bmpFrame); } else { return(bmp); } }
public void Read(BinaryReader reader, ref Palette_15Bit currentPalette) { FirstByte = reader.ReadByte(); if (FirstByte == 0) { // no data. All else is irrelevant. The whole resource is 1 byte of zero. return; } ImageWidth = reader.ReadInt32(); ImageHeight = reader.ReadInt32(); ImageOffsetX = reader.ReadInt32(); ImageOffsetY = reader.ReadInt32(); ImageHandle = reader.ReadInt32(); PaletteHandle = reader.ReadInt32(); BitsPerPixel = reader.ReadByte(); FrameHeight = reader.ReadByte(); // height comes before width. Why? FrameWidth = reader.ReadByte(); Alignment = reader.ReadByte(); // insanity if (ImageWidth < 0) { throw new InvalidDataException("Unexpected negative number for image width! (Value = {0})".F(ImageWidth)); } if (ImageHeight < 0) { throw new InvalidDataException("Unexpected negative number for image height! (Value = {0})".F(ImageHeight)); } if (FrameWidth < 0) { throw new InvalidDataException("Unexpected negative number for frame width! (Value = {0})".F(FrameWidth)); } if (FrameHeight < 0) { throw new InvalidDataException("Unexpected negative number for frame height! (Value = {0})".F(FrameHeight)); } int pixels = ImageWidth * ImageHeight; if (BitsPerPixel == 8) { ImageData = reader.ReadBytes(pixels); } else if (BitsPerPixel == 16) { ImageData = reader.ReadBytes(pixels * 2); } else { // pixelated insanity throw new InvalidDataException("Unexpected bits per pixel! (Value = {0})".F(BitsPerPixel)); } if (PaletteHandle == 0) { } if (PaletteHandle != 0) { if (BitsPerPixel == 8) { switch (PaletteType) { case PaletteType.EMBEDDED_PALETTE: Memory = reader.ReadInt32(); PaletteHandle2 = reader.ReadInt32(); currentPalette.Read(reader); break; case PaletteType.REFERENCED_PALETTE: break; } } Palette = currentPalette.Clone(); } }