Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
 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));
 }
Esempio n. 7
0
 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));
 }
Esempio n. 8
0
        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));
        }
Esempio n. 9
0
 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)]);
            }
        }