/// <summary> /// Dyes whole bitmap. Non grey pixels are first converted to grey and then dyed. /// </summary> /// <param name="hue">Colors spectrum that will be used.</param> /// <param name="bitmap">Bitmap that will be edited.</param> public static void RecolorFull(HueEntry hue, Bitmap bitmap) { if (hue == null) { throw new ArgumentNullException("hue"); } if (bitmap == null) { return; } if (bitmap.PixelFormat != PixelFormat.Format16bppArgb1555) { throw new ArgumentException("Invalid bitmap pixel format.", "source"); } BitmapData data = bitmap.LockBits(Ultima.GetBitmapBounds(bitmap), ImageLockMode.ReadWrite, PixelFormat.Format16bppArgb1555); Debug.Assert(data.Stride % 2 == 0, "data.Stride % 2 == 0"); RecolorFullInternal(hue, data.Scan0, data.Stride * data.Height / 2); bitmap.UnlockBits(data); }
/// <summary> /// Reads a TileID texture (44x44) from current position in specified file. /// </summary> /// <param name="stream">Stream where to read from.</param> /// <returns>New instance of Bitmap containing read texture.</returns> public static Bitmap ReadTile(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } Bitmap bitmap = new Bitmap(44, 44, PixelFormat.Format16bppArgb1555); BitmapData data = bitmap.LockBits(Ultima.GetBitmapBounds(bitmap), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555); byte[] buffer = new byte[44 * 2]; for (int y = 0; y < 22; y++) { int x = 22 - (y + 1); int lenght = (y + 1) * 2; stream.Read(buffer, 0, lenght * 2); for (int i = 0; i < lenght; i++) { buffer[i * 2 + 1] |= 0x80; } Marshal.Copy(buffer, 0, (IntPtr)((int)data.Scan0 + y * data.Stride + x * 2), lenght * 2); } for (int y = 22; y < 44; y++) { int x = y - 22; int lenght = (44 - y) * 2; stream.Read(buffer, 0, lenght * 2); for (int i = 0; i < lenght; i++) { buffer[i * 2 + 1] |= 0x80; } Marshal.Copy(buffer, 0, (IntPtr)((int)data.Scan0 + y * data.Stride + x * 2), lenght * 2); } bitmap.UnlockBits(data); return(bitmap); }
/// <summary> /// Reads a run-type texture from current position in specified file. /// </summary> /// <param name="stream">Stream where to read from.</param> /// <returns>New instance of Bitmap containing read texture.</returns> public static Bitmap ReadRun(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } BinaryReader reader = new BinaryReader(stream); int header = reader.ReadInt32(); int width = reader.ReadInt16(); int height = reader.ReadInt16(); Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppArgb1555); BitmapData data = bitmap.LockBits(Ultima.GetBitmapBounds(bitmap), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555); byte[] buffer = new byte[4096]; // Read lookup table ushort[] lookupTable = new ushort[height]; for (int i = 0; i < height; i++) { lookupTable[i] = reader.ReadUInt16(); } // list begining in file long dataPos = stream.Position; int y = 0; while (y < height) { // New line stream.Seek(dataPos + lookupTable[y] * 2, SeekOrigin.Begin); // ReadLine short xOffset; short xRun; int x = 0; do { xOffset = reader.ReadInt16(); xRun = reader.ReadInt16(); if (xOffset + xRun >= 2048) { throw new IOException("Corrupted list."); } // Read current chunk x += xOffset; stream.Read(buffer, 0, xRun * 2); for (int i = 0; i < xRun; i++) { buffer[i * 2 + 1] |= 0x80; } Marshal.Copy(buffer, 0, (IntPtr)((int)data.Scan0 + y * data.Stride + x * 2), xRun * 2); x += xRun; } while (xRun != 0 || xOffset != 0); y++; } bitmap.UnlockBits(data); return(bitmap); }