protected override void setBMPInternal(int index, ref Bitmap bmp) { if (this.file == null || !this.file.CanWrite) { throw new NotSupportedException("Stream is readonly"); } if (this.compatFixes) { throw new NotSupportedException("Input data had various compatibility fixes applied to be able to load! Cannot save with these."); } parsedImgData imgInfo = this.imgDatas[index]; if (bmp.Width != imgInfo.width || bmp.Height != imgInfo.height) { throw new NotSupportedException("New image has different dimensions"); } { PixelFormat pf; switch (imgInfo.type) { case 19: pf = PixelFormat.Format8bppIndexed; break; case 20: pf = PixelFormat.Format4bppIndexed; break; default: throw new NotSupportedException("Unsupported type"); } if (bmp.PixelFormat != pf) { requestQuantize(ref bmp, pf); } } /*Get the BAR subfile*/ byte[] barFile = this.BAR.fileList[imgInfo.barFile].data; using (BinaryReader br = new BinaryReader(new MemoryStream(barFile, true))) { br.BaseStream.Position = imgInfo.palBOffs; byte[] palData = getData(br, imgInfo.baseP), imgData; { byte[] palette = new byte[1024]; Array.Copy(palData, imgInfo.palOffs, palette, 0, palette.Length); imgData = TexUt2.Encode(bmp, ref palette, imgInfo.palCs); Array.Copy(palette, 0, palData, imgInfo.palOffs, palette.Length); } br.BaseStream.Position = imgInfo.palBOffs; setData(br, imgInfo.baseP, palData); br.BaseStream.Position = imgInfo.imgBOffs; setData(br, imgInfo.baseP, imgData); } this.BAR.fileList[imgInfo.barFile].data = barFile; this.file.Position = 0; this.BAR.save(new Crazycatz00.Utility.Substream(this.file)); }
private static Bitmap getImage(BinaryReader br, ref byte[] imgData, byte[] palData, long palOffs, parsedImgData info) { #if TRACE Trace.Assert(br.ReadUInt64() == 0x3fL); br.BaseStream.Position += 8; Trace.Assert(br.ReadUInt64() == 0x34L); br.BaseStream.Position += 8; Trace.Assert(br.ReadUInt64() == 0x36L); ulong num = br.ReadUInt64(); Trace.Assert(br.ReadUInt64() == 0x16L); Trace.Assert(((num >> 20) & 0x3f) == 0x13); Trace.Assert(((num >> 0x33) & 15) == 0); Trace.Assert(((num >> 0x37) & 1) == 0); Trace.Assert(((num >> 0x38) & 0x1f) == 0); Trace.Assert(((num >> 0x3d) & 7) == 4); br.BaseStream.Position += 8; Trace.Assert(br.ReadUInt64() == 0x14L); #else br.BaseStream.Position += 8 + 16 + 16 + 16 + 16; #endif num = br.ReadUInt64(); #if TRACE Trace.Assert(br.ReadUInt64() == 0x06L); Trace.Assert(((num >> 0x22) & 1) == 1); Trace.Assert(((num >> 0x33) & 15) == 0); Trace.Assert(((num >> 0x37) & 1) == 0); Trace.Assert(((num >> 0x3d) & 7) == 0); br.BaseStream.Position += 8; Trace.Assert(br.ReadUInt64() == 8L); #else //br.BaseStream.Position += 8 + 16; #endif info.type = (uint)(num >> 20) & 0x3fu; if (info.type != 19 && info.type != 20) { throw new NotSupportedException("Unknown t0PSM: " + info.type); } info.palOffs = (256 * ((uint)(num >> 0x25) & 0x3FFFu)) - palOffs; info.width = (ushort)(1u << ((int)(num >> 0x1A) & 0x0F)); info.height = (ushort)(1u << ((int)(num >> 0x1E) & 0x0F)); info.palCs = (byte)((uint)(num >> 0x38) & 0x1Fu); byte[] palette = new byte[1024]; if (info.palOffs < 0) { throw new NotSupportedException("Image palette located before block address."); } if (info.palOffs + palette.Length > palData.Length) { throw new NotSupportedException("Image palette located after block address."); } Array.Copy(palData, info.palOffs, palette, 0, palette.Length); int size = info.width * info.height; if (info.type == 20) { size /= 2; } if (imgData.Length < size) { Debug.WriteLine("Expected size = " + size + "; got = " + imgData.Length); Array.Resize <byte>(ref imgData, size); } return(TexUt2.Decode(imgData, palette, info.type, info.width, info.height, info.palCs)); }