public static Bitmap DecompressBC1(Byte[] data, int width, int height, bool IsSRGB) { int W = (width + 3) / 4; int H = (height + 3) / 4; byte[] Output = new byte[W * H * 64]; for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { int IOffs = (Y * W + X) * 8; byte[] Tile = BCnDecodeTile(data, IOffs, true); int TOffset = 0; for (int TY = 0; TY < 4; TY++) { for (int TX = 0; TX < 4; TX++) { int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4; Output[OOffset + 0] = Tile[TOffset + 0]; Output[OOffset + 1] = Tile[TOffset + 1]; Output[OOffset + 2] = Tile[TOffset + 2]; Output[OOffset + 3] = Tile[TOffset + 3]; TOffset += 4; } } } } return(BitmapExtension.GetBitmap(Output, W * 4, H * 4)); }
public override void SetImageData(Bitmap bitmap, int ArrayLevel) { byte[] Data = BitmapExtension.ImageToByte(bitmap); Width = (uint)bitmap.Width; Height = (uint)bitmap.Height; ImageData = DDSCompressor.EncodePixelBlock(Data, bitmap.Width, bitmap.Width, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); }
public static System.Drawing.Bitmap DecodeDataToBitmap(byte[] ImageData, byte[] PaletteData, uint width, uint height, TEX_FORMAT format, PALETTE_FORMAT palleteFormat) { var FormatGC = FromGenericFormat(format); var PalleteFormatGC = FromGenericPaletteFormat(palleteFormat); return(BitmapExtension.GetBitmap(DecodeData(ImageData, PaletteData, width, height, FormatGC, PalleteFormatGC), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); }
public static Bitmap DecompressBC4(Byte[] data, int width, int height, bool IsSNORM) { int W = (width + 3) / 4; int H = (height + 3) / 4; byte[] Output = new byte[W * H * 64]; for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { int IOffs = (Y * W + X) * 8; byte[] Red = new byte[8]; Red[0] = data[IOffs + 0]; Red[1] = data[IOffs + 1]; if (IsSNORM) { CalculateBC3AlphaS(Red); } else { CalculateBC3Alpha(Red); } int RedLow = Get32(data, IOffs + 2); int RedHigh = Get16(data, IOffs + 6); ulong RedCh = (uint)RedLow | (ulong)RedHigh << 32; int TOffset = 0; int TW = Math.Min(width - X * 4, 4); int TH = Math.Min(height - Y * 4, 4); for (int TY = 0; TY < 4; TY++) { for (int TX = 0; TX < 4; TX++) { int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4; byte RedPx = Red[(RedCh >> (TY * 12 + TX * 3)) & 7]; Output[OOffset + 0] = RedPx; Output[OOffset + 1] = RedPx; Output[OOffset + 2] = RedPx; Output[OOffset + 3] = 255; TOffset += 4; } } } } return(BitmapExtension.GetBitmap(Output, W * 4, H * 4)); }
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0) { if (TargaImage == null || TargaImage.Image == null) { return(new byte[0]); } return(BitmapExtension.ImageToByte(BitmapExtension.SwapBlueRedChannels(TargaImage.Image))); }
public Bitmap CreateScreenshot(int width, int height, bool useAlpha = false) { int imageSize = width * height * 4; GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); byte[] output = new byte[imageSize]; GL.ReadPixels(0, 0, width, height, PixelFormat.Bgra, PixelType.UnsignedByte, output); var bitmap = BitmapExtension.GetBitmap(output, width, height); bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); return(bitmap); }
public static Bitmap DecompressBC3(Byte[] data, int width, int height, bool IsSRGB) { int W = (width + 3) / 4; int H = (height + 3) / 4; byte[] Output = new byte[W * H * 64]; for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { int IOffs = (Y * W + X) * 16; byte[] Tile = BCnDecodeTile(data, IOffs + 8, false); byte[] Alpha = new byte[8]; Alpha[0] = data[IOffs + 0]; Alpha[1] = data[IOffs + 1]; CalculateBC3Alpha(Alpha); int AlphaLow = Get32(data, IOffs + 2); int AlphaHigh = Get16(data, IOffs + 6); ulong AlphaCh = (uint)AlphaLow | (ulong)AlphaHigh << 32; int TOffset = 0; for (int TY = 0; TY < 4; TY++) { for (int TX = 0; TX < 4; TX++) { int OOffset = (X * 4 + TX + (Y * 4 + TY) * W * 4) * 4; byte AlphaPx = Alpha[(AlphaCh >> (TY * 12 + TX * 3)) & 7]; Output[OOffset + 0] = Tile[TOffset + 0]; Output[OOffset + 1] = Tile[TOffset + 1]; Output[OOffset + 2] = Tile[TOffset + 2]; Output[OOffset + 3] = AlphaPx; TOffset += 4; } } } } return(BitmapExtension.GetBitmap(Output, W * 4, H * 4)); }
private void LoadBitmap(Bitmap Image) { Image = BitmapExtension.SwapBlueRedChannels(Image); Format = TEX_FORMAT.R8G8B8A8_UNORM; Width = (uint)Image.Width; Height = (uint)Image.Height; MipCount = 1; ImageData = GenerateMipsAndCompress(Image, MipCount, Format); if (ImageData == null || ImageData.Length <= 0) { throw new Exception("Image failed to encode!"); } }
private void ReloadTextureIcons(TreeNode node, Image image) { image = BitmapExtension.Resize(image, this.ImageList.ImageSize); if (node.ImageIndex != -1 && node.ImageIndex < this.ImageList.Images.Count) { this.ImageList.Images[node.ImageIndex] = image; } else { node.ImageIndex = this.ImageList.Images.Count; node.SelectedImageIndex = node.ImageIndex; this.ImageList.Images.Add(image); } this.Refresh(); }
public static System.Drawing.Bitmap DecodeDataToBitmap(byte[] ImageData, ushort[] PaletteData, uint width, uint height, TextureFormats format, PaletteFormats palleteFormat) { return(BitmapExtension.GetBitmap(DecodeData(ImageData, PaletteData, width, height, format, palleteFormat), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); }
public static Bitmap DecompressCompLibBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format, bool GetBitmap) { return(BitmapExtension.GetBitmap(DecompressBlock(data, width, height, format), (int)width, (int)height)); }
public static Bitmap DecompressBC5(Byte[] data, int width, int height, bool IsSNORM) { int W = (width + 3) / 4; int H = (height + 3) / 4; byte[] Output = new byte[W * H * 64]; for (int Y = 0; Y < H; Y++) { for (int X = 0; X < W; X++) { int IOffs = (Y * W + X) * 16; byte[] Red = new byte[8]; byte[] Green = new byte[8]; Red[0] = data[IOffs + 0]; Red[1] = data[IOffs + 1]; Green[0] = data[IOffs + 8]; Green[1] = data[IOffs + 9]; if (IsSNORM == true) { CalculateBC3AlphaS(Red); CalculateBC3AlphaS(Green); } else { CalculateBC3Alpha(Red); CalculateBC3Alpha(Green); } int RedLow = Get32(data, IOffs + 2); int RedHigh = Get16(data, IOffs + 6); int GreenLow = Get32(data, IOffs + 10); int GreenHigh = Get16(data, IOffs + 14); ulong RedCh = (uint)RedLow | (ulong)RedHigh << 32; ulong GreenCh = (uint)GreenLow | (ulong)GreenHigh << 32; int TW = Math.Min(width - X * 4, 4); int TH = Math.Min(height - Y * 4, 4); if (IsSNORM == true) { for (int TY = 0; TY < TH; TY++) { for (int TX = 0; TX < TW; TX++) { int Shift = TY * 12 + TX * 3; int OOffset = ((Y * 4 + TY) * width + (X * 4 + TX)) * 4; byte RedPx = Red[(RedCh >> Shift) & 7]; byte GreenPx = Green[(GreenCh >> Shift) & 7]; if (IsSNORM == true) { RedPx += 0x80; GreenPx += 0x80; } float NX = (RedPx / 255f) * 2 - 1; float NY = (GreenPx / 255f) * 2 - 1; float NZ = (float)Math.Sqrt(1 - (NX * NX + NY * NY)); Output[OOffset + 0] = Clamp((NZ + 1) * 0.5f); Output[OOffset + 1] = Clamp((NY + 1) * 0.5f); Output[OOffset + 2] = Clamp((NX + 1) * 0.5f); Output[OOffset + 3] = 0xff; } } } else { for (int TY = 0; TY < TH; TY++) { for (int TX = 0; TX < TW; TX++) { int Shift = TY * 12 + TX * 3; int OOffset = ((Y * 4 + TY) * width + (X * 4 + TX)) * 4; byte RedPx = Red[(RedCh >> Shift) & 7]; byte GreenPx = Green[(GreenCh >> Shift) & 7]; Output[OOffset + 0] = 255; Output[OOffset + 1] = GreenPx; Output[OOffset + 2] = RedPx; Output[OOffset + 3] = 255; } } } } } return(BitmapExtension.GetBitmap(Output, W * 4, H * 4)); }
public static System.Drawing.Bitmap DecodeBlockToBitmap(byte[] Input, int Width, int Height, PICASurfaceFormat picaFormat) { return(BitmapExtension.GetBitmap(DecodeBlock(Input, Width, Height, picaFormat), Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)); }
//Much help from encoding thanks to this // https://github.com/Cruel/3dstex/blob/master/src/Encoder.cpp public static byte[] EncodeBlock(byte[] Input, int Width, int Height, PICASurfaceFormat PicaFormat) { int ImageSize = CalculateLength(Width, Height, PicaFormat); if (PicaFormat == PICASurfaceFormat.ETC1) { return(SmashForge.RG_ETC1.encodeETC(BitmapExtension.GetBitmap(Input, Width, Height))); } else if (PicaFormat == PICASurfaceFormat.ETC1A4) { return(SmashForge.RG_ETC1.encodeETCa4(BitmapExtension.GetBitmap(Input, Width, Height))); } var mem = new System.IO.MemoryStream(); using (var writer = new FileWriter(mem)) { for (int TY = 0; TY < Height; TY += 8) { for (int TX = 0; TX < Width; TX += 8) { for (int Px = 0; Px < 64; Px++) { int X = SwizzleLUT[Px] & 7; int Y = (SwizzleLUT[Px] - X) >> 3; int IOffs = (TX + X + ((TY + Y) * Width)) * 4; if (PicaFormat == PICASurfaceFormat.RGBA8) { writer.Write(Input[IOffs + 3]); writer.Write(Input[IOffs + 0]); writer.Write(Input[IOffs + 1]); writer.Write(Input[IOffs + 2]); } else if (PicaFormat == PICASurfaceFormat.RGB8) { writer.Write(Input[IOffs + 0]); writer.Write(Input[IOffs + 1]); writer.Write(Input[IOffs + 2]); } else if (PicaFormat == PICASurfaceFormat.A8) { writer.Write(Input[IOffs]); } else if (PicaFormat == PICASurfaceFormat.L8) { writer.Write(ConvertBRG8ToL( new byte[] { Input[IOffs + 0], Input[IOffs + 1], Input[IOffs + 2] })); } else if (PicaFormat == PICASurfaceFormat.LA8) { writer.Write(Input[IOffs + 3]); writer.Write(ConvertBRG8ToL( new byte[] { Input[IOffs + 0], Input[IOffs + 1], Input[IOffs + 2] })); } else if (PicaFormat == PICASurfaceFormat.RGB565) { ushort R = (ushort)(Convert8To5(Input[IOffs + 0])); ushort G = (ushort)(Convert8To6(Input[IOffs + 1]) << 5); ushort B = (ushort)(Convert8To5(Input[IOffs + 2]) << 11); writer.Write((ushort)(R | G | B)); } else if (PicaFormat == PICASurfaceFormat.RGBA4) { ushort R = (ushort)(Convert8To4(Input[IOffs]) << 4); ushort G = (ushort)(Convert8To4(Input[IOffs + 1]) << 8); ushort B = (ushort)(Convert8To4(Input[IOffs + 2]) << 12); ushort A = (ushort)(Convert8To4(Input[IOffs + 3])); writer.Write((ushort)(R | G | B | A)); } else if (PicaFormat == PICASurfaceFormat.RGBA5551) { ushort R = (ushort)(Convert8To5(Input[IOffs + 0]) << 1); ushort G = (ushort)(Convert8To5(Input[IOffs + 1]) << 6); ushort B = (ushort)(Convert8To5(Input[IOffs + 2]) << 11); ushort A = (ushort)(Convert8To1(Input[IOffs + 3])); writer.Write((ushort)(R | G | B | A)); } else if (PicaFormat == PICASurfaceFormat.LA4) { byte A = Input[IOffs + 3]; byte L = ConvertBRG8ToL( new byte[] { Input[IOffs + 0], Input[IOffs + 1], Input[IOffs + 2] }); writer.Write((byte)((A >> 4) | (L & 0xF0))); } else if (PicaFormat == PICASurfaceFormat.L4) { //Skip alpha channel byte L1 = ConvertBRG8ToL( new byte[] { Input[IOffs + 0], Input[IOffs + 1], Input[IOffs + 2] }); byte L2 = ConvertBRG8ToL( new byte[] { Input[IOffs + 4], Input[IOffs + 5], Input[IOffs + 6] }); writer.Write((byte)((L1 >> 4) | (L2 & 0xF0))); Px++; } else if (PicaFormat == PICASurfaceFormat.A4) { byte A1 = (byte)(Input[IOffs + 3] >> 4); byte A2 = (byte)(Input[IOffs + 7] & 0xF0); writer.Write((byte)(A1 | A2)); Px++; } else if (PicaFormat == PICASurfaceFormat.HiLo8) { writer.Write(Input[IOffs]); writer.Write(Input[IOffs + 1]); } } } } } byte[] newOutput = mem.ToArray(); // if (newOutput.Length != ImageSize) // throw new Exception($"Invalid image size! Expected {ImageSize} got {newOutput.Length}"); if (newOutput.Length > 0) { return(newOutput); } else { return(new byte[CalculateLength(Width, Height, PicaFormat)]); } }