private static int SetTextureImage(byte[] Data, int Index, BinaryReader Reader = null) { int TextureFormat = (Data[Index + 1] & 0xE0) >> 5; int BitsPerPixel = (Data[Index + 1] & 0x18) >> 3; int Width = (((Data[Index + 2] << 8) | Data[Index + 3]) & 0x3FF) + 1; int Height = (((BitConverter.ToInt32(Data, 0).Reverse() >> 10) & 0xFF) + 1) * 4; int ImageAddress = (Data[Index + 4] << 24) | (Data[Index + 5] << 16) | (Data[Index + 6] << 8) | Data[Index + 7]; Debug.WriteLine(string.Format("Set Texture | Address: {0} | Texture Format: {1} | Bits Per Pixel: {2} | Width: {3} | Height: {4}", ImageAddress.ToString("X8"), TextureFormat, BitsPerPixel, Width, Height)); if (Reader != null && (ImageAddress & 0x80000000) != 0) { Reader.BaseStream.Seek(ImageAddress & ~0x80000000, SeekOrigin.Begin); int[] PixelData = C4.DecodeC4(Reader.ReadBytes((Width * Height) / 2), Palette.ToArray(), Width, Height); byte[] ImgData = new byte[PixelData.Length * 4]; Buffer.BlockCopy(PixelData, 0, ImgData, 0, ImgData.Length); BitmapSource Img = Util.ToImage(ImgData, Width, Height); MainWindowReference.Texture = Img; using (var FStream = new FileStream(ImageOutputDirectory + "\\Image_" + ImageAddress.ToString("X8") + ".png", FileMode.Create)) { var Encoder = new PngBitmapEncoder(); Encoder.Frames.Add(BitmapFrame.Create(Img)); Encoder.Save(FStream); } } return(8); }
public TextureEntry(int textureOffset, int width, int height, byte[] textureData, ref ushort[] paletteData, ref uint[] rgba8Palette, int index) { TextureOffset = textureOffset; Width = width; Height = height; Palette = paletteData; Rgba8Palette = rgba8Palette; RawData = textureData; Argb8Data = C4.DecodeC4(textureData, Palette, width, height, GCNToolKit.ColorFormat.RGB5A3); Texture = Utility.CreateBitmap(Argb8Data, width, height); EntryIndex = index; }
public BTI(byte[] data) { Data = data; Header = new BTI_Header(data); Bitmap_Data = new byte[Header.Width * Header.Height * 4]; if (Header.Image_Format == ImageFormat.RGB565 || Header.Image_Format == ImageFormat.RGB5A3) { ushort[] PixelData = new ushort[(data.Length - 0x20) / 2]; for (int i = 0, idx = 0x20; i < PixelData.Length; i++, idx += 2) { PixelData[i] = (ushort)((data[idx] << 8) | data[idx + 1]); } // Decode Block Format PixelData = SwizzleUtil.Unswizzle(PixelData, Header.Width, Header.Height, 4, 4); Bitmap_Data = new byte[PixelData.Length * 4]; for (int i = 0, idx = 0; i < PixelData.Length; i++, idx += 4) { byte A = 0, R = 0, G = 0, B = 0; if (Header.Image_Format == ImageFormat.RGB5A3) { RGB5A3.ToARGB8(PixelData[i], out A, out R, out G, out B); } else { A = 0xFF; RGB565.ToARGB8(PixelData[i], out R, out G, out B); } Bitmap_Data[idx] = B; Bitmap_Data[idx + 1] = G; Bitmap_Data[idx + 2] = R; Bitmap_Data[idx + 3] = A; } } else if (Header.Image_Format == ImageFormat.RGBA8) { } else { switch (Header.Palette_Format) { case PixelFormat.RGB565: case PixelFormat.RGB5A3: Palette = new ushort[Header.Palette_Entry_Count]; for (int i = 0; i < Header.Palette_Entry_Count; i++) { int offset = (int)(Header.Palette_Offset + i * 2); Palette[i] = (ushort)((Data[offset] << 8) | Data[offset + 1]); } break; } switch (Header.Image_Format) { case ImageFormat.I4: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(((Header.Width * Header.Height) + 1) / 2).ToArray(); Buffer.BlockCopy(I4.DecodeI4(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length); break; case ImageFormat.I8: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray(); Buffer.BlockCopy(I8.DecodeI8(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length); break; case ImageFormat.IA4: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray(); Buffer.BlockCopy(IA4.DecodeIA4(Image_Data, Header.Width, Header.Height, Color.White), 0, Bitmap_Data, 0, Bitmap_Data.Length); break; case ImageFormat.IA8: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take((Header.Width * Header.Height) * 2).ToArray(); Buffer.BlockCopy(IA8.DecodeIA8(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length); break; case ImageFormat.C4: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take((Header.Width * Header.Height) / 2).ToArray(); Buffer.BlockCopy(C4.DecodeC4(Image_Data, Palette, Header.Width, Header.Height, (ColorFormat)Header.Palette_Format), 0, Bitmap_Data, 0, Bitmap_Data.Length); break; case ImageFormat.C8: Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray(); int Index = 0; for (int blockY = 0; blockY < Header.Height; blockY += 4) { for (int blockX = 0; blockX < Header.Width; blockX += 8) { for (int Y = 0; Y < 4; Y++) { for (int X = 0; X < 8; X++) { ushort Pixel = Palette[Image_Data[Index]]; int New_Index = Header.Width * (blockY + Y) + blockX + X; byte A = 0, R = 0, G = 0, B = 0; switch (Header.Palette_Format) { case PixelFormat.RGB565: RGB565.ToARGB8(Pixel, out R, out G, out B); A = 0xFF; break; case PixelFormat.RGB5A3: RGB5A3.ToARGB8(Pixel, out A, out R, out G, out B); break; default: throw new NotImplementedException("Pixel format is not implemented!"); } Bitmap_Data[New_Index * 4] = B; Bitmap_Data[New_Index * 4 + 1] = G; Bitmap_Data[New_Index * 4 + 2] = R; Bitmap_Data[New_Index * 4 + 3] = A; Index++; } } } } break; default: throw new NotImplementedException("Image Format is not implemented!"); } } Bitmap_Image = Utilities.BitmapUtilities.CreateBitmap(Bitmap_Data, Header.Width, Header.Height); }