Exemple #1
0
        internal static ImageSource DecompressTextureToImageSource(byte[] imageData, int width, int height, bool ignoreAlpha, IPixelEffect effect, uint fourCC, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
        {
            using (var imageStream = new MemoryStream(imageData))
            {
                byte[] pixelColors;

                if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT1)
                {
                    pixelColors = DxtUtil.DecompressDxt1(imageStream, width, height);
                }
                else if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT3)
                {
                    pixelColors = DxtUtil.DecompressDxt3(imageStream, width, height);
                }
                else
                {
                    pixelColors = DxtUtil.DecompressDxt5(imageStream, width, height, dxgiFormat);
                }

                // Copy the pixel colors into a byte array
                const int bytesPerPixel = 4;
                var       stride        = width * bytesPerPixel;
                var       pixelRgba     = new byte[pixelColors.Length];
                for (var i = 0; i < pixelColors.Length; i += bytesPerPixel)
                {
                    pixelRgba[i + 0] = pixelColors[i + 2];
                    pixelRgba[i + 1] = pixelColors[i + 1];
                    pixelRgba[i + 2] = pixelColors[i + 0];
                    pixelRgba[i + 3] = ignoreAlpha ? (byte)0xff : pixelColors[i + 3];
                }

                if (effect == null)
                {
                    return(System.Windows.Media.Imaging.BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgra32, null, pixelRgba, stride));
                }

                var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat);

                //Copy the data from the byte array into BitmapData.Scan0
                Marshal.Copy(pixelRgba, 0, bmpData.Scan0, pixelRgba.Length);

                // Unlock the pixels
                bmp.UnlockBits(bmpData);

                bmp = effect.Quantize(bmp);

                return(ImageHelper.ConvertBitmapToBitmapImage(bmp));
            }
        }
Exemple #2
0
        internal static Bitmap DecompressTextureToBitmap(byte[] imageData, int width, int height, bool ignoreAlpha, uint fourCC, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
        {
            using (var imageStream = new MemoryStream(imageData))
            {
                byte[] pixelColors;

                if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT1)
                {
                    pixelColors = DxtUtil.DecompressDxt1(imageStream, width, height);
                }
                else if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT3)
                {
                    pixelColors = DxtUtil.DecompressDxt3(imageStream, width, height);
                }
                else
                {
                    pixelColors = DxtUtil.DecompressDxt5(imageStream, width, height, dxgiFormat);
                }

                // Copy the pixel colors into a byte array
                const int bytesPerPixel = 4;
                var       pixelRgba     = new byte[pixelColors.Length];
                for (var i = 0; i < pixelColors.Length; i += bytesPerPixel)
                {
                    pixelRgba[i + 0] = pixelColors[i + 2];
                    pixelRgba[i + 1] = pixelColors[i + 1];
                    pixelRgba[i + 2] = pixelColors[i + 0];
                    pixelRgba[i + 3] = ignoreAlpha ? (byte)0xff : pixelColors[i + 3];
                }

                // Here create the Bitmap to the know height, width and format
                var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                // Create a BitmapData and Lock all pixels to be written
                var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat);

                //Copy the data from the byte array into BitmapData.Scan0
                Marshal.Copy(pixelRgba, 0, bmpData.Scan0, pixelRgba.Length);

                // Unlock the pixels
                bmp.UnlockBits(bmpData);

                return(bmp);
            }
        }
Exemple #3
0
        private static void DecompressDxt5Block(BinaryReader imageReader, int x, int y, int blockCountX, int width, int height, byte[] imageData, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
        {
            byte alpha0 = imageReader.ReadByte();
            byte alpha1 = imageReader.ReadByte();

            ulong alphaMask = (ulong)imageReader.ReadByte();

            alphaMask += (ulong)imageReader.ReadByte() << 8;
            alphaMask += (ulong)imageReader.ReadByte() << 16;
            alphaMask += (ulong)imageReader.ReadByte() << 24;
            alphaMask += (ulong)imageReader.ReadByte() << 32;
            alphaMask += (ulong)imageReader.ReadByte() << 40;

            ushort c0 = imageReader.ReadUInt16();
            ushort c1 = imageReader.ReadUInt16();

            byte r0, g0, b0;
            byte r1, g1, b1;

            switch (dxgiFormat)
            {
            case ImageTextureUtil.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                break;

            case ImageTextureUtil.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN:
                break;

            default:
                break;
            }

            ConvertRgb565ToRgb888(c0, out r0, out g0, out b0);
            ConvertRgb565ToRgb888(c1, out r1, out g1, out b1);

            uint lookupTable = imageReader.ReadUInt32();

            for (int blockY = 0; blockY < 4; blockY++)
            {
                for (int blockX = 0; blockX < 4; blockX++)
                {
                    byte r = 0, g = 0, b = 0, a = 255;
                    uint index = (lookupTable >> 2 * (4 * blockY + blockX)) & 0x03;

                    uint alphaIndex = (uint)((alphaMask >> 3 * (4 * blockY + blockX)) & 0x07);
                    if (alphaIndex == 0)
                    {
                        a = alpha0;
                    }
                    else if (alphaIndex == 1)
                    {
                        a = alpha1;
                    }
                    else if (alpha0 > alpha1)
                    {
                        a = (byte)(((8 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 7);
                    }
                    else if (alphaIndex == 6)
                    {
                        a = 0;
                    }
                    else if (alphaIndex == 7)
                    {
                        a = 0xff;
                    }
                    else
                    {
                        a = (byte)(((6 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 5);
                    }

                    switch (index)
                    {
                    case 0:
                        r = r0;
                        g = g0;
                        b = b0;
                        break;

                    case 1:
                        r = r1;
                        g = g1;
                        b = b1;
                        break;

                    case 2:
                        r = (byte)((2 * r0 + r1) / 3);
                        g = (byte)((2 * g0 + g1) / 3);
                        b = (byte)((2 * b0 + b1) / 3);
                        break;

                    case 3:
                        r = (byte)((r0 + 2 * r1) / 3);
                        g = (byte)((g0 + 2 * g1) / 3);
                        b = (byte)((b0 + 2 * b1) / 3);
                        break;
                    }

                    int px = (x << 2) + blockX;
                    int py = (y << 2) + blockY;
                    if ((px < width) && (py < height))
                    {
                        int offset = ((py * width) + px) << 2;
                        imageData[offset]     = r;
                        imageData[offset + 1] = g;
                        imageData[offset + 2] = b;
                        imageData[offset + 3] = a;
                    }
                }
            }
        }
Exemple #4
0
        internal static byte[] DecompressDxt5(Stream imageStream, int width, int height, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
        {
            byte[] imageData = new byte[width * height * 4];

            using (BinaryReader imageReader = new BinaryReader(imageStream))
            {
                if (dxgiFormat == ImageTextureUtil.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB)
                {
                    int blockSize = 8;
                    // For block-compressed formats, compute the pitch as:
                    int dwPitchOrLinearSize = Math.Max(1, ((width + 3) / 4)) * blockSize;
                }

                int blockCountX = (width + 3) / 4;
                int blockCountY = (height + 3) / 4;

                for (int y = 0; y < blockCountY; y++)
                {
                    for (int x = 0; x < blockCountX; x++)
                    {
                        DecompressDxt5Block(imageReader, x, y, blockCountX, width, height, imageData, dxgiFormat);
                    }
                }
            }

            return(imageData);
        }
Exemple #5
0
 internal static byte[] DecompressDxt5(byte[] imageData, int width, int height, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
 {
     using (MemoryStream imageStream = new MemoryStream(imageData))
     {
         return(DecompressDxt5(imageStream, width, height, dxgiFormat));
     }
 }
Exemple #6
0
        private static void DecompressDxt5Block(BinaryReader imageReader, int x, int y, int blockCountX, int width, int height, byte[] imageData, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
        {
            byte alpha0 = imageReader.ReadByte();
            byte alpha1 = imageReader.ReadByte();

            ulong alphaMask = (ulong)imageReader.ReadByte();

            alphaMask += (ulong)imageReader.ReadByte() << 8;
            alphaMask += (ulong)imageReader.ReadByte() << 16;
            alphaMask += (ulong)imageReader.ReadByte() << 24;
            alphaMask += (ulong)imageReader.ReadByte() << 32;
            alphaMask += (ulong)imageReader.ReadByte() << 40;

            ushort c0 = imageReader.ReadUInt16();
            ushort c1 = imageReader.ReadUInt16();

            byte r0, g0, b0;
            byte r1, g1, b1;

            switch (dxgiFormat)
            {
            case ImageTextureUtil.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                // there is suport to be some sort of SRGB conversion somwhere here, but I'm not sure where precicly and on what values.

                //ConvertSrgbToRgb888(c0, out r0, out g0, out b0);
                //ConvertSrgbToRgb888(c1, out r1, out g1, out b1);

                var aa = (byte)(255 * D3DX_SRGB_to_FLOAT_inexact(((float)(c0 & 0x000000ff)) / 255));
                r0 = (byte)(255 * D3DX_SRGB_to_FLOAT_inexact(((float)(((c0 >> 8) & 0x000000ff))) / 255));
                g0 = (byte)(255 * D3DX_SRGB_to_FLOAT_inexact(((float)(c1 & 0x000000ff)) / 255));
                b0 = (byte)(255 * D3DX_SRGB_to_FLOAT_inexact(((float)(((c1 >> 8) & 0x000000ff))) / 255));

                r1 = r0;
                g1 = g0;
                b1 = b0;

                break;

            case ImageTextureUtil.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN:
            default:
                ConvertRgb565ToRgb888(c0, out r0, out g0, out b0);
                ConvertRgb565ToRgb888(c1, out r1, out g1, out b1);
                break;
            }


            uint lookupTable = imageReader.ReadUInt32();

            for (int blockY = 0; blockY < 4; blockY++)
            {
                for (int blockX = 0; blockX < 4; blockX++)
                {
                    byte r = 0, g = 0, b = 0, a = 255;
                    uint index = (lookupTable >> 2 * (4 * blockY + blockX)) & 0x03;

                    uint alphaIndex = (uint)((alphaMask >> 3 * (4 * blockY + blockX)) & 0x07);
                    if (alphaIndex == 0)
                    {
                        a = alpha0;
                    }
                    else if (alphaIndex == 1)
                    {
                        a = alpha1;
                    }
                    else if (alpha0 > alpha1)
                    {
                        a = (byte)(((8 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 7);
                    }
                    else if (alphaIndex == 6)
                    {
                        a = 0;
                    }
                    else if (alphaIndex == 7)
                    {
                        a = 0xff;
                    }
                    else
                    {
                        a = (byte)(((6 - alphaIndex) * alpha0 + (alphaIndex - 1) * alpha1) / 5);
                    }

                    switch (index)
                    {
                    case 0:
                        r = r0;
                        g = g0;
                        b = b0;
                        break;

                    case 1:
                        r = r1;
                        g = g1;
                        b = b1;
                        break;

                    case 2:
                        r = (byte)((2 * r0 + r1) / 3);
                        g = (byte)((2 * g0 + g1) / 3);
                        b = (byte)((2 * b0 + b1) / 3);
                        break;

                    case 3:
                        r = (byte)((r0 + 2 * r1) / 3);
                        g = (byte)((g0 + 2 * g1) / 3);
                        b = (byte)((b0 + 2 * b1) / 3);
                        break;
                    }

                    int px = (x << 2) + blockX;
                    int py = (y << 2) + blockY;
                    if ((px < width) && (py < height))
                    {
                        int offset = ((py * width) + px) << 2;
                        imageData[offset]     = r;
                        imageData[offset + 1] = g;
                        imageData[offset + 2] = b;
                        imageData[offset + 3] = a;
                    }
                }
            }
        }