private static void setData(BinaryReader br, long baseP, byte[] data) { ulong num = br.ReadUInt64(); int bw = ((int)(num >> 0x30)) & 0x3F; uint type = ((uint)(num >> 0x38)) & 0x3F; br.BaseStream.Position += 8 + 16 + 16 + 16; int size = (br.ReadUInt16() & 0x7FFF) << 4; br.BaseStream.Position += 0x12L; br.BaseStream.Position = baseP + br.ReadInt32(); Debug.WriteLine("writing:bw = " + bw + "; type = " + type + "; size = " + size); int ds = size / 8192; switch (type) { case 0: if (bw > 0) { data = Reform.Decode32(data, bw, ds / bw); } break; case 19: bw /= 2; if (bw > 0) { data = Reform.Decode8(data, bw, ds / bw); } break; case 20: bw /= 2; if (bw > 0) { data = Reform.Decode4(data, bw, ds / bw); } break; default: throw new NotSupportedException("Unknown type: " + type); } Debug.WriteLine("Writing " + size + " bytes..."); Debug.WriteLineIf(size < data.Length, "Expected " + size + " bytes, but got " + data.Length + " bytes; Truncating!"); Debug.WriteLineIf(size > data.Length, "Expected " + size + " bytes, but only got " + data.Length + " bytes!"); br.BaseStream.Write(data, 0, Math.Min(size, (int)Math.Min(data.Length, br.BaseStream.Length - br.BaseStream.Position))); }
protected override void setBMPInternal(int index, ref Bitmap bmp) { if (!this.file.CanWrite) { throw new NotSupportedException("Stream is readonly."); } long pos = getIMGDOffset(index); this.file.Seek(pos, SeekOrigin.Begin); if (this.file.ReadUInt32() != 0x44474D49) { throw new InvalidDataException("IMGD has bad signature."); } this.file.Seek(4, SeekOrigin.Current); uint pixelOffset = this.file.ReadUInt32(), pixelLength = this.file.ReadUInt32(), paletteOffset = this.file.ReadUInt32(), paletteLength = this.file.ReadUInt32(); this.file.Seek(4, SeekOrigin.Current); ushort width = this.file.ReadUInt16(), height = this.file.ReadUInt16(); this.file.Seek(6, SeekOrigin.Current); ushort type = this.file.ReadUInt16(); this.file.Seek(20, SeekOrigin.Current); byte encode = this.file.ReadByte(); if (bmp.Width != width || bmp.Height != height) { throw new NotSupportedException("New image has different dimensions."); } PixelFormat pf; switch (type) { case 19: pf = PixelFormat.Format8bppIndexed; break; case 20: pf = PixelFormat.Format4bppIndexed; break; default: throw new NotSupportedException("Unsupported IMGD type"); } if (bmp.PixelFormat != pf) { requestQuantize(ref bmp, pf); } { BitmapData pix = bmp.LockBits(System.Drawing.Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, pf); byte[] buffer = new byte[pixelLength]; try { System.Runtime.InteropServices.Marshal.Copy(pix.Scan0, buffer, 0, (int)pixelLength); } finally { bmp.UnlockBits(pix); } switch (pf) { case PixelFormat.Format8bppIndexed: if (encode == 7) { buffer = Reform.Decode32(Reform.Encode8(buffer, width / 128, height / 64), width / 128, height / 64); } break; case PixelFormat.Format4bppIndexed: if (encode == 7) { buffer = Reform.Decode32(Reform.Encode4(buffer, width / 128, height / 128), width / 128, height / 128); } else { Reform.swapHLUT(buffer); } break; } this.file.Seek(pos + pixelOffset, SeekOrigin.Begin); this.file.Write(buffer, 0, (int)pixelLength); } { ColorPalette palette = bmp.Palette; byte[] buffer = new byte[paletteLength]; switch (pf) { case PixelFormat.Format8bppIndexed: for (int i = 0; i < 256; i++) { uint argb = (uint)palette.Entries[Reform.paletteSwap34(i)].ToArgb(); buffer[(i * 4) + 3] = (byte)Math.Ceiling((double)(argb >> 24) / 2); buffer[i * 4] = (byte)(argb >> 16); buffer[i * 4 + 1] = (byte)(argb >> 8); buffer[i * 4 + 2] = (byte)argb; } break; case PixelFormat.Format4bppIndexed: for (int i = 0; i < 16; i++) { uint argb = (uint)palette.Entries[i].ToArgb(); buffer[(i * 4) + 3] = (byte)Math.Ceiling((double)(argb >> 24) / 2); buffer[i * 4] = (byte)(argb >> 16); buffer[i * 4 + 1] = (byte)(argb >> 8); buffer[i * 4 + 2] = (byte)argb; } break; } this.file.Seek(pos + paletteOffset, SeekOrigin.Begin); this.file.Write(buffer, 0, (int)paletteLength); } }