static void BitmapAssert(BitmapContent bitmap, Color color, int range)
        {
            byte[] rgba;
            if (bitmap is Dxt1BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt1(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else if (bitmap is Dxt3BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt3(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else if (bitmap is Dxt5BitmapContent)
            {
                rgba = DxtUtil.DecompressDxt5(bitmap.GetPixelData(), bitmap.Width, bitmap.Height);
            }
            else
            {
                rgba = bitmap.GetPixelData();
            }

            for (var p = 0; p < rgba.Length; p += 4)
            {
                Assert.That(rgba[p + 0], Is.EqualTo(color.R).Within(range));
                Assert.That(rgba[p + 1], Is.EqualTo(color.G).Within(range));
                Assert.That(rgba[p + 2], Is.EqualTo(color.B).Within(range));
                Assert.That(rgba[p + 3], Is.EqualTo(color.A).Within(range));
            }
        }
Пример #2
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            int           width         = reader.ReadInt32();
            int           height        = reader.ReadInt32();
            int           levelCount    = reader.ReadInt32();
            int           imageLength   = reader.ReadInt32();

            byte[] imageData = reader.ReadBytes(imageLength);

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1: imageData = DxtUtil.DecompressDxt1(imageData, width, height); break;

            case SurfaceFormat.Dxt3: imageData = DxtUtil.DecompressDxt3(imageData, width, height); break;
            }

            IntPtr imagePtr = IntPtr.Zero;


            // Changed to load the raw data
            // currentony only ARGB8888 is supported
            ESTexture2D esTexture = new ESTexture2D(imageData, surfaceFormat, width, height, new Size(width, height), All.Linear);

            texture = new Texture2D(reader.GraphicsDevice, new ESImage(esTexture));


            return(texture);
        }
Пример #3
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            int           width         = reader.ReadInt32();
            int           height        = reader.ReadInt32();
            int           levelCount    = reader.ReadInt32();
            int           imageLength   = reader.ReadInt32();

            byte[] imageData = reader.ReadBytes(imageLength);

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1: imageData = DxtUtil.DecompressDxt1(imageData, width, height); break;

            case SurfaceFormat.Dxt3: imageData = DxtUtil.DecompressDxt3(imageData, width, height); break;
            }

            IntPtr imagePtr = IntPtr.Zero;

            try
            {
                imagePtr = Marshal.AllocHGlobal(imageData.Length);
                Marshal.Copy(imageData, 0, imagePtr, imageData.Length);
                ESTexture2D esTexture = new ESTexture2D(imagePtr, surfaceFormat, width, height, new Size(width, height), All.Linear);
                texture = new Texture2D(new ESImage(esTexture));
            }
            finally
            {
                Marshal.FreeHGlobal(imagePtr);
            }

            return(texture);
        }
Пример #4
0
 public byte[] DecompressData()
 {
     if (Format == SurfaceFormat.Alpha8)
     {
         return(Alpha8ToRgba(Data));
     }
     else if (Format == SurfaceFormat.Color)
     {
         return(Data);
     }
     else if (Format == SurfaceFormat.Dxt5)
     {
         return(DxtUtil.DecompressDxt5(Data, Width, Height));
     }
     else if (Format == (SurfaceFormat)28)
     {
         return(DetexCS.DetexCS.DecodeBc7(Data, Width, Height));
     }
     else if (Format == (SurfaceFormat)27)
     {
         return(LumAlpha8ToRgba(Data));
     }
     else
     {
         throw new PsigaShimUnsupported();
     }
 }
Пример #5
0
        /// <summary>
        /// Exports RenderSurface to a image file
        /// </summary>
        public void ExportTexture(string directory)
        {
            string      ext          = ".png";
            ImageFormat exportFormat = ImageFormat.Png;

            if (Length > 0)
            {
                switch (Format)
                {
                case SurfacePixelFormat.PFID_CUSTOM_RAW_JPEG:
                {
                    ext = ".jpg";
                    string filename = Path.Combine(directory, Id.ToString("X8") + ext);
                    using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)))
                    {
                        writer.Write(SourceData);
                    }
                }
                break;

                case SurfacePixelFormat.PFID_DXT1:
                {
                    byte[] bitmapData  = DxtUtil.DecompressDxt1(SourceData, Width, Height);
                    Bitmap bitmapImage = GetBitmap(bitmapData);
                    string filename    = Path.Combine(directory, Id.ToString("X8") + ext);
                    bitmapImage.Save(filename, exportFormat);
                }
                break;

                case SurfacePixelFormat.PFID_DXT3:
                {
                    byte[] bitmapData  = DxtUtil.DecompressDxt3(SourceData, Width, Height);
                    Bitmap bitmapImage = GetBitmap(bitmapData);
                    string filename    = Path.Combine(directory, Id.ToString("X8") + ext);
                    bitmapImage.Save(filename, exportFormat);
                }
                break;

                case SurfacePixelFormat.PFID_DXT5:
                {
                    byte[] bitmapData  = DxtUtil.DecompressDxt5(SourceData, Width, Height);
                    Bitmap bitmapImage = GetBitmap(bitmapData);
                    string filename    = Path.Combine(directory, Id.ToString("X8") + ext);
                    bitmapImage.Save(filename, exportFormat);
                }
                break;

                default:
                {
                    List <int> colors      = GetImageColorArray();
                    Bitmap     bitmapImage = GetBitmap(colors);
                    string     filename    = Path.Combine(directory, Id.ToString("X8") + ext);
                    bitmapImage.Save(filename, exportFormat);
                }
                break;
                }
            }
        }
Пример #6
0
        public void TestDxt5Compress()
        {
            var    resPath  = Path.Combine(Environment.CurrentDirectory, @"..\..\Res");
            var    rawPng   = Path.Combine(resPath, "D愛子a_春服-pure", "0.png");
            Bitmap bitmap   = new Bitmap(rawPng);
            var    bc3Bytes = DxtUtil.Dxt5Encode(bitmap);

            RL.ConvertToImageFile(bc3Bytes, rawPng + "-convert.png", 4096, 4096, PsbImageFormat.Png, PsbPixelFormat.DXT5);
        }
Пример #7
0
        /// <summary>
        /// Gets the raw pixel data for the texture
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <returns>A byte array with the image data</returns>
        public Task <byte[]> GetImageData(XivTex xivTex)
        {
            return(Task.Run(async() =>
            {
                byte[] imageData = null;

                switch (xivTex.TextureFormat)
                {
                case XivTexFormat.DXT1:
                    imageData = DxtUtil.DecompressDxt1(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.DXT3:
                    imageData = DxtUtil.DecompressDxt3(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.DXT5:
                    imageData = DxtUtil.DecompressDxt5(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.A4R4G4B4:
                    imageData = await Read4444Image(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.A1R5G5B5:
                    imageData = await Read5551Image(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.A8R8G8B8:
                    imageData = await SwapRBColors(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.L8:
                case XivTexFormat.A8:
                    imageData = await Read8bitImage(xivTex.TexData, xivTex.Width, xivTex.Height);
                    break;

                case XivTexFormat.X8R8G8B8:
                case XivTexFormat.R32F:
                case XivTexFormat.G16R16F:
                case XivTexFormat.G32R32F:
                case XivTexFormat.A16B16G16R16F:
                case XivTexFormat.A32B32G32R32F:
                case XivTexFormat.D16:
                default:
                    imageData = xivTex.TexData;
                    break;
                }

                return imageData;
            }));
        }
Пример #8
0
        /// <summary>
        /// Creates a bitmap from the texture data.
        /// </summary>
        /// <param name="decompressedData">The decompressed data of the texture.</param>
        /// <param name="textureType">The textures type.</param>
        /// <param name="width">The textures width.</param>
        /// <param name="height">The textures height.</param>
        /// <returns>The created bitmap.</returns>
        //public static Bitmap TextureToBitmap(byte[] decompressedData, int textureType, int width, int height)
        public static void TextureToBitmap(byte[] decompressedData, TEXData texData)
        {
            BitmapSource bmpSource;
            var          width  = texData.Width;
            var          height = texData.Height;
            Tuple <BitmapSource, BitmapSource> bmps = null;

            byte[] decompressedTextureData;

            switch (texData.Type)
            {
            case TextureTypes.DXT1:
                decompressedTextureData = DxtUtil.DecompressDxt1(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT3:
                decompressedTextureData = DxtUtil.DecompressDxt3(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT5:
                decompressedTextureData = DxtUtil.DecompressDxt5(decompressedData, width, height);
                bmps = Read32bitBitmapImageAlphaDXT(decompressedTextureData, width, height);
                break;

            case TextureTypes.A8:
            case TextureTypes.L8:
                bmpSource = Read8bitBitmapImage(decompressedData, width, height);
                bmps      = new Tuple <BitmapSource, BitmapSource>(bmpSource, bmpSource);
                break;

            case TextureTypes.A4R4G4B4:
                bmps = Read4444BMPSource(decompressedData, width, height);
                break;

            case TextureTypes.A1R5G5B5:
                bmps = Read5551BMPSource(decompressedData, width, height);
                break;

            case TextureTypes.A8R8G8B8:
            case TextureTypes.X8R8G8B8:
                bmps = Read32bitBitmapImageAlpha(decompressedData, width, height);
                break;
                //case TextureTypes.A16B16G16R16F:
                //    bmp = ReadRGBAFImage(decompressedData, width, height);
                //    break;
            }

            texData.BMPSouceAlpha   = bmps.Item1;
            texData.BMPSouceNoAlpha = bmps.Item2;
        }
Пример #9
0
        /// <summary>
        /// Creates a bitmap from the texture data.
        /// </summary>
        /// <param name="decompressedData">The decompressed data of the texture.</param>
        /// <param name="textureType">The textures type.</param>
        /// <param name="width">The textures width.</param>
        /// <param name="height">The textures height.</param>
        /// <returns>The created bitmap.</returns>
        public static Bitmap TextureToBitmap(byte[] decompressedData, int textureType, int width, int height)
        {
            Bitmap bmp = null;

            byte[] decompressedTextureData;

            switch (textureType)
            {
            case TextureTypes.DXT1:
                decompressedTextureData = DxtUtil.DecompressDxt1(decompressedData, width, height);
                bmp = ReadLinearImage(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT3:
                decompressedTextureData = DxtUtil.DecompressDxt3(decompressedData, width, height);
                bmp = ReadLinearImage(decompressedTextureData, width, height);
                break;

            case TextureTypes.DXT5:
                decompressedTextureData = DxtUtil.DecompressDxt5(decompressedData, width, height);
                bmp = ReadLinearImage(decompressedTextureData, width, height);
                break;

            case TextureTypes.A8:
            case TextureTypes.L8:
                bmp = Read8bitImage(decompressedData, width, height);
                break;

            case TextureTypes.A4R4G4B4:
                bmp = Read4444Image(decompressedData, width, height);
                break;

            case TextureTypes.A1R5G5B5:
                bmp = Read5551Image(decompressedData, width, height);
                //bmp = new Bitmap(width, height, width * 2, System.Drawing.Imaging.PixelFormat.Format16bppArgb1555, Marshal.UnsafeAddrOfPinnedArrayElement(decompressedData, 0));
                break;

            case TextureTypes.A8R8G8B8:
            case TextureTypes.X8R8G8B8:
                var u = Marshal.UnsafeAddrOfPinnedArrayElement(decompressedData, 0);
                bmp = new Bitmap(width, height, width * 4,
                                 System.Drawing.Imaging.PixelFormat.Format32bppArgb, u);
                break;

            case TextureTypes.A16B16G16R16F:
                bmp = ReadRGBAFImage(decompressedData, width, height);
                break;
            }

            return(bmp);
        }
Пример #10
0
        /// <summary>
        /// Gets the raw pixel data for the texture
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <returns>A byte array with the image data</returns>
        public byte[] GetImageData(XivTex xivTex)
        {
            byte[] imageData = null;

            switch (xivTex.TextureFormat)
            {
            case XivTexFormat.DXT1:
                imageData = DxtUtil.DecompressDxt1(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.DXT3:
                imageData = DxtUtil.DecompressDxt3(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.DXT5:
                imageData = DxtUtil.DecompressDxt5(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.A4R4G4B4:
                imageData = Read4444Image(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.A1R5G5B5:
                imageData = Read5551Image(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.A8R8G8B8:
                imageData = SwapRBColors(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.L8:
            case XivTexFormat.A8:
                imageData = Read8bitImage(xivTex.TexData, xivTex.Width, xivTex.Heigth);
                break;

            case XivTexFormat.X8R8G8B8:
            case XivTexFormat.R32F:
            case XivTexFormat.G16R16F:
            case XivTexFormat.G32R32F:
            case XivTexFormat.A16B16G16R16F:
            case XivTexFormat.A32B32G32R32F:
            case XivTexFormat.D16:
            default:
                imageData = xivTex.TexData;
                break;
            }

            return(imageData);
        }
Пример #11
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            int           width         = reader.ReadInt32();
            int           height        = reader.ReadInt32();

            /*int levelCount =*/ reader.ReadInt32();
            int imageLength = reader.ReadInt32();

            byte[] imageData = reader.ReadBytes(imageLength);

#if NO_DXT35
            System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
            sw2.Reset();
            sw2.Start();
            // GG TODO need to remove this manual decompression KTHX
            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1: imageData = DxtUtil.DecompressDxt1(imageData, width, height); surfaceFormat = SurfaceFormat.Rgba32; break;

            case SurfaceFormat.Dxt3: imageData = DxtUtil.DecompressDxt3(imageData, width, height); surfaceFormat = SurfaceFormat.Rgba32; break;
            }
            if (sw2.ElapsedMilliseconds > 16)
            {
                GSGE.Debug.logMessage("Surface Format decompression took " + sw2.ElapsedMilliseconds);
            }
#endif

            unsafe
            {
                fixed(byte *pData = imageData)
                {
                    ESTexture2D esTexture = new ESTexture2D((IntPtr)pData,
                                                            imageData.Length,
                                                            surfaceFormat,
                                                            width, height,
                                                            new Size(width, height),
                                                            All.Linear);

                    texture = new Texture2D(new ESImage(esTexture));
                }
            }

            return(texture);
        }
Пример #12
0
        public void Convert(PSB psb)
        {
            if (!FromSpec.Contains(psb.Platform))
            {
                throw new FormatException("Can not convert Spec for this PSB");
            }

            var asSpec        = EmsAsCommon ? PsbSpec.ems : PsbSpec.common;
            var toSpec        = psb.Platform == PsbSpec.win ? asSpec : PsbSpec.win;
            var toPixelFormat = toSpec == asSpec ? PsbPixelFormat.CommonRGBA8 : PsbPixelFormat.WinRGBA8;
            var resList       = psb.CollectResources <ImageMetadata>(false);

            foreach (var resMd in resList)
            {
                var resourceData = resMd.Resource.Data;
                if (resourceData == null)
                {
                    continue;
                }
                if (resMd.Compress == PsbCompressType.RL)
                {
                    resourceData = RL.Decompress(resourceData);
                }
                if (resMd.PixelFormat == PsbPixelFormat.DXT5)
                {
                    resourceData = RL.GetPixelBytesFromImage(
                        DxtUtil.Dxt5Decode(resourceData, resMd.Width, resMd.Height), toPixelFormat);
                    resMd.TypeString.Value = toPixelFormat.ToStringForPsb();
                }
                else
                {
                    RL.Switch_0_2(ref resourceData);
                    if (UseRL)
                    {
                        resourceData = RL.Compress(resourceData);
                    }
                }
                resMd.Resource.Data = resourceData;
            }
            psb.Platform = toSpec;
        }
        public void LoadOddSizedDxtCompressed()
        {
            // This is testing that DXT compressed mip levels that
            // are not a multiple of 4 are properly loaded.

            var t = content.Load <Texture2D>(Paths.Texture("red_668_dxt"));

            Assert.AreEqual(SurfaceFormat.Dxt1, t.Format);
            Assert.AreEqual(10, t.LevelCount);
            Assert.AreEqual(668, t.Width);
            Assert.AreEqual(668, t.Height);

            for (var m = 0; m < t.LevelCount; m++)
            {
                var w    = ((t.Width >> m) + 3) & ~3;
                var h    = ((t.Height >> m) + 3) & ~3;
                var size = w * h / 2;

                // Get the full mip level.
                var b = new byte[size];
                t.GetData(m, null, b, 0, size);

                // Decompress it to validate it.
                var b2 = DxtUtil.DecompressDxt1(b, t.Width >> m, t.Height >> m);

                // Should be a red opaque texture.
                for (var p = 0; p < b2.Length; p += 4)
                {
                    Assert.AreEqual(255, b2[p + 0]);
                    Assert.AreEqual(0, b2[p + 1]);
                    Assert.AreEqual(0, b2[p + 2]);
                    Assert.AreEqual(255, b2[p + 3]);
                }
            }

            t.Dispose();
        }
Пример #14
0
        /// <summary>
        /// Reads RenderSurface to bitmap structure
        /// </summary>
        public Bitmap GetBitmap()
        {
            switch (Format)
            {
            case SurfacePixelFormat.PFID_CUSTOM_RAW_JPEG:
            {
                var stream = new MemoryStream(SourceData);
                var image  = Image.FromStream(stream);
                return(new Bitmap(image));
            }

            case SurfacePixelFormat.PFID_DXT1:
            {
                var image = DxtUtil.DecompressDxt1(SourceData, Width, Height);
                return(GetBitmap(image));
            }

            case SurfacePixelFormat.PFID_DXT3:
            {
                var image = DxtUtil.DecompressDxt3(SourceData, Width, Height);
                return(GetBitmap(image));
            }

            case SurfacePixelFormat.PFID_DXT5:
            {
                var image = DxtUtil.DecompressDxt5(SourceData, Width, Height);
                return(GetBitmap(image));
            }

            default:
            {
                List <int> colors = GetImageColorArray();
                return(GetBitmap(colors));
            }
            }
        }
Пример #15
0
        /// <summary>
        /// Gets the raw pixel data for the texture
        /// </summary>
        /// <param name="xivTex">The texture data</param>
        /// <returns>A byte array with the image data</returns>
        public Task <byte[]> GetImageData(XivTex xivTex, int layer = -1)
        {
            return(Task.Run(async() =>
            {
                byte[] imageData = null;

                var layers = xivTex.Layers;
                if (layers == 0)
                {
                    layers = 1;
                }

                switch (xivTex.TextureFormat)
                {
                case XivTexFormat.DXT1:
                    imageData = DxtUtil.DecompressDxt1(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.DXT3:
                    imageData = DxtUtil.DecompressDxt3(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.DXT5:
                    imageData = DxtUtil.DecompressDxt5(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.A4R4G4B4:
                    imageData = await Read4444Image(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.A1R5G5B5:
                    imageData = await Read5551Image(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.A8R8G8B8:
                    imageData = await SwapRBColors(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.L8:
                case XivTexFormat.A8:
                    imageData = await Read8bitImage(xivTex.TexData, xivTex.Width, xivTex.Height * layers);
                    break;

                case XivTexFormat.X8R8G8B8:
                case XivTexFormat.R32F:
                case XivTexFormat.G16R16F:
                case XivTexFormat.G32R32F:
                case XivTexFormat.A16B16G16R16F:
                case XivTexFormat.A32B32G32R32F:
                case XivTexFormat.D16:
                default:
                    imageData = xivTex.TexData;
                    break;
                }

                if (layer >= 0)
                {
                    var bytesPerLayer = imageData.Length / xivTex.Layers;
                    var offset = bytesPerLayer * layer;

                    byte[] nData = new byte[bytesPerLayer];
                    Array.Copy(imageData, offset, nData, 0, bytesPerLayer);

                    imageData = nData;
                }

                return imageData;
            }));
        }
Пример #16
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            var surfaceFormat    = (SurfaceFormat)reader.ReadInt32();
            int width            = reader.ReadInt32();
            int height           = reader.ReadInt32();
            int levelCount       = reader.ReadInt32();
            int levelCountOutput = levelCount;

            // If the system does not fully support Power of Two textures,
            // skip any mip maps supplied with any non PoT textures.
            if (levelCount > 1 && !reader.GetGraphicsDevice().Capabilities.SupportsNonPowerOfTwo&&
                (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height)))
            {
                levelCountOutput = 1;
                System.Diagnostics.Debug.WriteLine(
                    "Device does not support non Power of Two textures. Skipping mipmaps.");
            }

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1a:
                if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Rgba32;
                }
                break;

            case SurfaceFormat.Dxt1SRgb:
                if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Rgba32SRgb;
                }
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Rgba32;
                }
                break;

            case SurfaceFormat.Dxt3SRgb:
            case SurfaceFormat.Dxt5SRgb:
                if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Rgba32SRgb;
                }
                break;

            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Rgba32;
                break;
            }

            var texture = existingInstance ?? new Texture2D(
                reader.GetGraphicsDevice(), width, height, levelCountOutput > 1, convertedFormat);

            for (int level = 0; level < levelCountOutput; level++)
            {
                int levelDataSizeInBytes = reader.ReadInt32();
                using (var levelDataBuffer = reader.ContentManager.GetScratchBuffer(levelDataSizeInBytes))
                {
                    byte[] levelData = levelDataBuffer.Buffer;
                    if (reader.Read(levelData.AsSpan(0, levelDataSizeInBytes)) != levelDataSizeInBytes)
                    {
                        throw new InvalidDataException();
                    }

                    int levelWidth  = Math.Max(width >> level, 1);
                    int levelHeight = Math.Max(height >> level, 1);

                    //Convert the image data if required
                    switch (surfaceFormat)
                    {
                    case SurfaceFormat.Dxt1:
                    case SurfaceFormat.Dxt1SRgb:
                    case SurfaceFormat.Dxt1a:
                        if (!reader.GetGraphicsDevice().Capabilities.SupportsDxt1&&
                            convertedFormat == SurfaceFormat.Rgba32)
                        {
                            levelData            = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                            levelDataSizeInBytes = levelData.Length;
                        }
                        break;

                    case SurfaceFormat.Dxt3:
                    case SurfaceFormat.Dxt3SRgb:
                        if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc&&
                            convertedFormat == SurfaceFormat.Rgba32)
                        {
                            levelData            = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                            levelDataSizeInBytes = levelData.Length;
                        }
                        break;

                    case SurfaceFormat.Dxt5:
                    case SurfaceFormat.Dxt5SRgb:
                        if (!reader.GetGraphicsDevice().Capabilities.SupportsS3tc&&
                            convertedFormat == SurfaceFormat.Rgba32)
                        {
                            levelData            = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                            levelDataSizeInBytes = levelData.Length;
                        }
                        break;

                    case SurfaceFormat.NormalizedByte4:
                    {
                        int bytesPerPixel = surfaceFormat.GetSize();
                        int pitch         = levelWidth * bytesPerPixel;
                        for (int y = 0; y < levelHeight; y++)
                        {
                            for (int x = 0; x < levelWidth; x++)
                            {
                                int color = BinaryPrimitives.ReadInt32LittleEndian(
                                    levelData.AsSpan(y * pitch + x * bytesPerPixel));

                                levelData[y * pitch + x * 4]     = (byte)((color >> 16) & 0xff); //R:=W
                                levelData[y * pitch + x * 4 + 1] = (byte)((color >> 8) & 0xff);  //G:=V
                                levelData[y * pitch + x * 4 + 2] = (byte)((color) & 0xff);       //B:=U
                                levelData[y * pitch + x * 4 + 3] = (byte)((color >> 24) & 0xff); //A:=Q
                            }
                        }
                    }
                    break;

#if OPENGL
                    case SurfaceFormat.Bgra5551:
                    {
                        // Shift the channels to suit OpenGL
                        int offset = 0;
                        for (int y = 0; y < levelHeight; y++)
                        {
                            for (int x = 0; x < levelWidth; x++)
                            {
                                ushort pixel = BinaryPrimitives.ReadUInt16LittleEndian(levelData.AsSpan(offset));
                                pixel                 = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15));
                                levelData[offset]     = (byte)pixel;
                                levelData[offset + 1] = (byte)(pixel >> 8);
                                offset               += 2;
                            }
                        }
                    }
                    break;

                    case SurfaceFormat.Bgra4444:
                    {
                        // Shift the channels to suit OpenGL
                        int offset = 0;
                        for (int y = 0; y < levelHeight; y++)
                        {
                            for (int x = 0; x < levelWidth; x++)
                            {
                                ushort pixel = BinaryPrimitives.ReadUInt16LittleEndian(levelData.AsSpan(offset));
                                pixel                 = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                                levelData[offset]     = (byte)pixel;
                                levelData[offset + 1] = (byte)(pixel >> 8);
                                offset               += 2;
                            }
                        }
                    }
                    break;
#endif
                    }
                    texture.SetData(levelData.AsSpan(0, levelDataSizeInBytes), null, level);
                }
            }

            return(texture);
        }
Пример #17
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
		{
			Texture2D texture = null;

            var surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            int width = reader.ReadInt32();
            int height = reader.ReadInt32();
            int levelCount = reader.ReadInt32();
            int levelCountOutput = levelCount;

            // If the system does not fully support Power of Two textures,
            // skip any mip maps supplied with any non PoT textures.
            if (levelCount > 1 && !reader.GraphicsDevice.GraphicsCapabilities.SupportsNonPowerOfTwo &&
                (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height)))
            {
                levelCountOutput = 1;
                System.Diagnostics.Debug.WriteLine(
                    "Device does not support non Power of Two textures. Skipping mipmaps.");
            }

			SurfaceFormat convertedFormat = surfaceFormat;
			switch (surfaceFormat)
			{
				case SurfaceFormat.Dxt1:
				case SurfaceFormat.Dxt1a:
					if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1)
						convertedFormat = SurfaceFormat.Color;
					break;
				case SurfaceFormat.Dxt1SRgb:
					if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1)
						convertedFormat = SurfaceFormat.ColorSRgb;
					break;
				case SurfaceFormat.Dxt3:
				case SurfaceFormat.Dxt5:
					if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
						convertedFormat = SurfaceFormat.Color;
					break;
				case SurfaceFormat.Dxt3SRgb:
				case SurfaceFormat.Dxt5SRgb:
					if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
						convertedFormat = SurfaceFormat.ColorSRgb;
					break;
				case SurfaceFormat.NormalizedByte4:
					convertedFormat = SurfaceFormat.Color;
					break;
			}
			
            texture = existingInstance ?? new Texture2D(reader.GraphicsDevice, width, height, levelCountOutput > 1, convertedFormat);
#if OPENGL
            Threading.BlockOnUIThread(() =>
            {
#endif
                for (int level = 0; level < levelCount; level++)
			    {
				    var levelDataSizeInBytes = reader.ReadInt32();
                    var levelData = reader.ContentManager.GetScratchBuffer(levelDataSizeInBytes);
                    reader.Read(levelData, 0, levelDataSizeInBytes);
                    int levelWidth = width >> level;
                    int levelHeight = height >> level;

                    if (level >= levelCountOutput)
                        continue;

				    //Convert the image data if required
				    switch (surfaceFormat)
				    {
					    case SurfaceFormat.Dxt1:
                        case SurfaceFormat.Dxt1SRgb:
                        case SurfaceFormat.Dxt1a:
				            if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1 && convertedFormat == SurfaceFormat.Color)
				            {
				                levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
				                levelDataSizeInBytes = levelData.Length;
				            }
				            break;
					    case SurfaceFormat.Dxt3:
					    case SurfaceFormat.Dxt3SRgb:
                            if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
				                if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc &&
				                    convertedFormat == SurfaceFormat.Color)
				                {
				                    levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                                    levelDataSizeInBytes = levelData.Length;
                                }
				            break;
					    case SurfaceFormat.Dxt5:
					    case SurfaceFormat.Dxt5SRgb:
                            if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
				                if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc &&
				                    convertedFormat == SurfaceFormat.Color)
				                {
				                    levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                                    levelDataSizeInBytes = levelData.Length;
                                }
				            break;
                        case SurfaceFormat.Bgra5551:
                            {
#if OPENGL
                                // Shift the channels to suit OpenGL
                                int offset = 0;
                                for (int y = 0; y < levelHeight; y++)
                                {
                                    for (int x = 0; x < levelWidth; x++)
                                    {
                                        ushort pixel = BitConverter.ToUInt16(levelData, offset);
                                        pixel = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15));
                                        levelData[offset] = (byte)(pixel);
                                        levelData[offset + 1] = (byte)(pixel >> 8);
                                        offset += 2;
                                    }
                                }
#endif
                            }
                            break;
					    case SurfaceFormat.Bgra4444:
						    {
#if OPENGL
                                // Shift the channels to suit OpenGL
							    int offset = 0;
							    for (int y = 0; y < levelHeight; y++)
							    {
								    for (int x = 0; x < levelWidth; x++)
								    {
									    ushort pixel = BitConverter.ToUInt16(levelData, offset);
									    pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
									    levelData[offset] = (byte)(pixel);
									    levelData[offset + 1] = (byte)(pixel >> 8);
									    offset += 2;
								    }
							    }
#endif
						    }
						    break;
					    case SurfaceFormat.NormalizedByte4:
						    {
							    int bytesPerPixel = surfaceFormat.GetSize();
							    int pitch = levelWidth * bytesPerPixel;
							    for (int y = 0; y < levelHeight; y++)
							    {
								    for (int x = 0; x < levelWidth; x++)
								    {
									    int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel);
									    levelData[y * pitch + x * 4] = (byte)(((color >> 16) & 0xff)); //R:=W
									    levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff)); //G:=V
									    levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff)); //B:=U
									    levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff)); //A:=Q
								    }
							    }
						    }
						    break;
				    }
				
                    texture.SetData(level, null, levelData, 0, levelDataSizeInBytes);
			    }
#if OPENGL
            });
#endif
        			
			return texture;
		}
Пример #18
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                /* These integer values are based on the enum values
                 * from previous XNA versions.
                 * -flibit
                 */
                int legacyFormat = reader.ReadInt32();
                if (legacyFormat == 1)
                {
                    surfaceFormat = SurfaceFormat.ColorBgraEXT;
                }
                else if (legacyFormat == 28)
                {
                    surfaceFormat = SurfaceFormat.Dxt1;
                }
                else if (legacyFormat == 30)
                {
                    surfaceFormat = SurfaceFormat.Dxt3;
                }
                else if (legacyFormat == 32)
                {
                    surfaceFormat = SurfaceFormat.Dxt5;
                }
                else
                {
                    throw new NotSupportedException(
                              "Unsupported legacy surface format."
                              );
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }
            int width            = reader.ReadInt32();
            int height           = reader.ReadInt32();
            int levelCount       = reader.ReadInt32();
            int levelCountOutput = levelCount;

            GraphicsDevice device = reader.ContentManager.GetGraphicsDevice();

            // Check to see if we need to convert the surface data
            SurfaceFormat convertedFormat = surfaceFormat;

            if (surfaceFormat == SurfaceFormat.Dxt1 &&
                !device.GLDevice.SupportsDxt1)
            {
                convertedFormat = SurfaceFormat.Color;
            }
            else if ((surfaceFormat == SurfaceFormat.Dxt3 ||
                      surfaceFormat == SurfaceFormat.Dxt5) &&
                     !device.GLDevice.SupportsS3tc)
            {
                convertedFormat = SurfaceFormat.Color;
            }

            // Check for duplicate instances
            if (existingInstance == null)
            {
                texture = new Texture2D(
                    device,
                    width,
                    height,
                    levelCountOutput > 1,
                    convertedFormat
                    );
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level += 1)
            {
                int    levelDataSizeInBytes = reader.ReadInt32();
                byte[] levelData            = null;      // Don't assign this quite yet...
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                if (level >= levelCountOutput)
                {
                    continue;
                }

                // Swap the image data if required.
                if (reader.platform == 'x')
                {
                    if (surfaceFormat == SurfaceFormat.Color ||
                        surfaceFormat == SurfaceFormat.ColorBgraEXT)
                    {
                        levelData = X360TexUtil.SwapColor(
                            reader.ReadBytes(levelDataSizeInBytes)
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        levelData = X360TexUtil.SwapDxt1(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        levelData = X360TexUtil.SwapDxt3(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        levelData = X360TexUtil.SwapDxt5(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                }

                // Convert the image data if required
                if (convertedFormat != surfaceFormat)
                {
                    // May already be read in by 'x' conversion
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        levelData = DxtUtil.DecompressDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        levelData = DxtUtil.DecompressDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        levelData = DxtUtil.DecompressDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    levelDataSizeInBytes = levelData.Length;
                }

                int levelDataByteOffset = 0;
                if (levelData == null)
                {
                    if (reader.BaseStream is MemoryStream &&
                        ((MemoryStream)reader.BaseStream).TryGetBuffer(out levelData))
                    {
                        /* Ideally, we didn't have to perform any conversion or
                         * unnecessary reading. Just throw the buffer directly
                         * into SetData, skipping a redundant byte[] copy.
                         */
                        levelDataByteOffset = (int)reader.BaseStream.Seek(0, SeekOrigin.Current);
                        reader.BaseStream.Seek(
                            levelDataSizeInBytes,
                            SeekOrigin.Current
                            );
                    }
                    else
                    {
                        /* If we don't have to perform any conversion and
                         * the ContentReader is not backed by a MemoryStream
                         * with a public buffer, we have to read the data in.
                         */
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                }
                texture.SetData(
                    level,
                    null,
                    levelData,
                    levelDataByteOffset,
                    levelDataSizeInBytes
                    );
            }

            return(texture);
        }
Пример #19
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormat_Legacy legacyFormat = (SurfaceFormat_Legacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }

            int width      = (reader.ReadInt32());
            int height     = (reader.ReadInt32());
            int levelCount = (reader.ReadInt32());

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
#if IPHONE
            // At the moment. If a DXT Texture comes in on iOS, it's really a PVR compressed
            // texture. We need to use this hack until the content pipeline is implemented.
            // For now DXT5 means we're using 4bpp PVRCompression and DXT3 means 2bpp. Look at
            // PvrtcBitmapContent.cs for more information.:
            case SurfaceFormat.Dxt3:
                convertedFormat = SurfaceFormat.RgbaPvrtc2Bpp;
                break;

            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.RgbaPvrtc4Bpp;
                break;
#elif ANDROID || PSS
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.Color;
                break;
#endif
            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }

            if (existingInstance == null)
            {
                texture = new Texture2D(reader.GraphicsDevice, width, height, levelCount > 1, convertedFormat);
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level++)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = reader.ReadBytes(levelDataSizeInBytes);
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                //Convert the image data if required
                switch (surfaceFormat)
                {
#if ANDROID || PSS
                //no Dxt in OpenGL ES
                case SurfaceFormat.Dxt1:
                    levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt3:
                    levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt5:
                    levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                    break;
#endif
                case SurfaceFormat.Bgr565:
                {
                    /*
                     * // BGR -> BGR
                     * int offset = 0;
                     * for (int y = 0; y < levelHeight; y++)
                     * {
                     *      for (int x = 0; x < levelWidth; x++)
                     *      {
                     *              ushort pixel = BitConverter.ToUInt16(levelData, offset);
                     *              pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                     *              levelData[offset] = (byte)(pixel);
                     *              levelData[offset + 1] = (byte)(pixel >> 8);
                     *              offset += 2;
                     *      }
                     * }
                     */
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
                    // Shift the channels to suit GLES
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    int bytesPerPixel = surfaceFormat.Size();
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel);
                            levelData[y * pitch + x * 4]     = (byte)(((color >> 16) & 0xff));                                       //R:=W
                            levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff));                                        //G:=V
                            levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff));                                             //B:=U
                            levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff));                                       //A:=Q
                        }
                    }
                }
                break;
                }

                texture.SetData(level, null, levelData, 0, levelData.Length);
            }

            return(texture);
        }
Пример #20
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormatLegacy legacyFormat = (SurfaceFormatLegacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormatLegacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormatLegacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormatLegacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormatLegacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotSupportedException("Unsupported legacy surface format.");
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }

            int width            = (reader.ReadInt32());
            int height           = (reader.ReadInt32());
            int levelCount       = (reader.ReadInt32());
            int levelCountOutput = levelCount;

            // If the system does not fully support Power of Two textures,
            // skip any mip maps supplied with any non PoT textures.
            if (levelCount > 1 && !reader.GraphicsDevice.GraphicsCapabilities.SupportsNonPowerOfTwo &&
                (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height)))
            {
                levelCountOutput = 1;
                System.Diagnostics.Debug.WriteLine(
                    "Device does not support non Power of Two textures. Skipping mipmaps.");
            }

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
#if IOS
            // At the moment. If a DXT Texture comes in on iOS, it's really a PVR compressed
            // texture. We need to use this hack until the content pipeline is implemented.
            // For now DXT5 means we're using 4bpp PVRCompression and DXT3 means 2bpp. Look at
            // PvrtcBitmapContent.cs for more information.:
            case SurfaceFormat.Dxt3:
                convertedFormat = SurfaceFormat.RgbaPvrtc2Bpp;
                break;

            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.RgbaPvrtc4Bpp;
                break;
#else
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1a:
                if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;
#endif
            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }

            if (existingInstance == null)
            {
                texture = new Texture2D(reader.GraphicsDevice, width, height, levelCountOutput > 1, convertedFormat);
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level++)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = reader.ReadBytes(levelDataSizeInBytes);
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;

                if (level >= levelCountOutput)
                {
                    continue;
                }

                //Convert the image data if required
                switch (surfaceFormat)
                {
#if !IOS
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt1a:
                    if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsDxt1)
                    {
                        levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                    }
                    break;

                case SurfaceFormat.Dxt3:
                    if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
                    {
                        levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                    }
                    break;

                case SurfaceFormat.Dxt5:
                    if (!reader.GraphicsDevice.GraphicsCapabilities.SupportsS3tc)
                    {
                        levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                    }
                    break;
#endif
                case SurfaceFormat.Bgr565:
                {
                    /*
                     * // BGR -> BGR
                     * int offset = 0;
                     * for (int y = 0; y < levelHeight; y++)
                     * {
                     *      for (int x = 0; x < levelWidth; x++)
                     *      {
                     *              ushort pixel = BitConverter.ToUInt16(levelData, offset);
                     *              pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                     *              levelData[offset] = (byte)(pixel);
                     *              levelData[offset + 1] = (byte)(pixel >> 8);
                     *              offset += 2;
                     *      }
                     * }
                     */
                }
                break;

                case SurfaceFormat.Bgra5551:
                {
#if OPENGL
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
#endif
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
#if OPENGL
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
#endif
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    int bytesPerPixel = surfaceFormat.GetSize();
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel);
                            levelData[y * pitch + x * 4]     = (byte)(((color >> 16) & 0xff));                                       //R:=W
                            levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff));                                        //G:=V
                            levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff));                                             //B:=U
                            levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff));                                       //A:=Q
                        }
                    }
                }
                break;
                }

                texture.SetData(level, null, levelData, 0, levelData.Length);
            }

            return(texture);
        }
Пример #21
0
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (fileOpen == false || listBox1.SelectedIndex == -1)
            {
                return;
            }

            int x = listBox1.SelectedIndex;

            string[] split      = listBox1.Items[x].ToString().Split(' ');
            int      actualNtp3 = int.Parse(split[1]);
            int      actualGidx = int.Parse(split[2]);

            //MessageBox.Show(actualNtp3.ToString("X2") + ", " + actualGidx.ToString("X2"));

            int resx = Main.b_byteArrayToIntRev(new byte[] { 0, 0,
                                                             gidxHeaders[actualNtp3][actualGidx][0x14],
                                                             gidxHeaders[actualNtp3][actualGidx][0x15] });

            int resy = Main.b_byteArrayToIntRev(new byte[] { 0, 0,
                                                             gidxHeaders[actualNtp3][actualGidx][0x16],
                                                             gidxHeaders[actualNtp3][actualGidx][0x17] });

            w_texsize.Text = "Texture size: " + resx.ToString() + "x" + resy.ToString();

            /*string a = "";
             * for(int b = 0; b < gidxHeaders[actualNtp3][actualGidx].Length; b++)
             * {
             *  a = a + gidxHeaders[actualNtp3][actualGidx][b].ToString("X2") + " ";
             * }
             * MessageBox.Show(a);*/

            byte texType = gidxHeaders[actualNtp3][actualGidx][0x13];

            byte[] rawimg = new byte[0];

            switch (texType)
            {
            default:
                w_textype.Text    = "Texture type: Unknown";
                pictureBox1.Image = blackImage;
                break;

            case 0:
                w_textype.Text = "Texture type: DXT1";
                rawimg         = DxtUtil.DecompressDxt1(textureData[actualNtp3][actualGidx], resx, resy);
                break;

            case 1:
                w_textype.Text = "Texture type: DXT3/DXT5 with mipmaps";
                rawimg         = DxtUtil.DecompressDxt5(textureData[actualNtp3][actualGidx], resx, resy);
                break;

            case 2:
                w_textype.Text = "Texture type: DXT3/DXT5";
                rawimg         = DxtUtil.DecompressDxt5(textureData[actualNtp3][actualGidx], resx, resy);
                break;

            case 8:
                w_textype.Text    = "Texture type: 5.6.5";
                pictureBox1.Image = blackImage;
                break;
            }

            if (rawimg.Length > 0)
            {
                bmp = new Bitmap(resx, resy, PixelFormat.Format32bppArgb);
                BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, resx, resy), ImageLockMode.WriteOnly, bmp.PixelFormat);
                Marshal.Copy(rawimg, 0, bmpData.Scan0, resx * resy * 4);
                bmp.UnlockBits(bmpData);
                pictureBox1.Image = bmp;
            }
        }
Пример #22
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormatLegacy legacyFormat = (SurfaceFormatLegacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormatLegacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormatLegacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormatLegacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormatLegacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotSupportedException("Unsupported legacy surface format.");
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }

            int width            = (reader.ReadInt32());
            int height           = (reader.ReadInt32());
            int levelCount       = (reader.ReadInt32());
            int levelCountOutput = levelCount;

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1a:
                convertedFormat = SurfaceFormat.Color;
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.Color;
                break;

            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }

            UnityEngine.Texture2D unityTexture = new UnityEngine.Texture2D(width, height, XnaToUnity.TextureFormat(convertedFormat), levelCountOutput > 1);

            for (int level = 0; level < levelCount; level++)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = reader.ReadBytes(levelDataSizeInBytes);
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;

                if (level >= levelCountOutput)
                {
                    continue;
                }

                //Convert the image data if required
                switch (surfaceFormat)
                {
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt1a:
                    levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt3:
                    levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt5:
                    levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                    break;
                }

                // un-premultiply alpha (instead do it in the shader)
                for (int i = 0; i < levelData.Length; i += 4)
                {
                    float r = levelData[i + 0] / 255.0f;
                    float g = levelData[i + 1] / 255.0f;
                    float b = levelData[i + 2] / 255.0f;
                    float a = levelData[i + 3] / 255.0f;

                    levelData[i + 0] = (byte)(r / a * 255.0f);
                    levelData[i + 1] = (byte)(g / a * 255.0f);
                    levelData[i + 2] = (byte)(b / a * 255.0f);

                    //levelData[i + 0] = 0;
                    //levelData[i + 1] = 255;
                    //levelData[i + 2] = 0;
                    //levelData[i + 3] = 255;
                }

                // swap rows because unity textures are laid out bottom-top instead of top-bottom
                int    rowSize = width * 4;
                byte[] temp    = new byte[rowSize];
                for (int i = 0; i < levelData.Length / 2; i += rowSize)
                {
                    for (int j = 0; j < rowSize; j++)
                    {
                        temp[j] = levelData[i + j];
                    }
                    int p = levelData.Length - (i + rowSize);
                    for (int j = 0; j < rowSize; j++)
                    {
                        levelData[i + j] = levelData[p + j];
                    }
                    for (int j = 0; j < rowSize; j++)
                    {
                        levelData[p + j] = temp[j];
                    }
                }

                UnityEngine.Color[] unityColors = new UnityEngine.Color[levelData.Length * 4];
                unityTexture.SetPixels(XnaToUnity.Color(levelData, ref unityColors), level);
                unityTexture.Apply();
                texture = new Texture2D(unityTexture);
            }
            return(texture);
        }
Пример #23
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                switch ((SurfaceFormat_Legacy)reader.ReadInt32())
                {
                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }
            int width1  = reader.ReadInt32();
            int height1 = reader.ReadInt32();
            int num1    = reader.ReadInt32();
            int num2    = num1;

            if (num1 > 1 && !GraphicsCapabilities.NonPowerOfTwo && (!MathHelper.IsPowerOfTwo(width1) || !MathHelper.IsPowerOfTwo(height1)))
            {
                num2 = 1;
            }
            SurfaceFormat format = surfaceFormat;

            if (surfaceFormat == SurfaceFormat.NormalizedByte4)
            {
                format = SurfaceFormat.Color;
            }
            if (!GraphicsExtensions.UseDxtCompression)
            {
                switch (surfaceFormat)
                {
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt3:
                case SurfaceFormat.Dxt5:
                    format = SurfaceFormat.Color;
                    break;
                }
            }
            Texture2D texture2D = existingInstance != null ? existingInstance : new Texture2D(reader.GraphicsDevice, width1, height1, num2 > 1, format);

            for (int level = 0; level < num1; ++level)
            {
                int    count    = reader.ReadInt32();
                byte[] numArray = reader.ReadBytes(count);
                int    width2   = width1 >> level;
                int    height2  = height1 >> level;
                if (level < num2)
                {
                    if (!GraphicsExtensions.UseDxtCompression)
                    {
                        switch (surfaceFormat)
                        {
                        case SurfaceFormat.Dxt1:
                            numArray = DxtUtil.DecompressDxt1(numArray, width2, height2);
                            break;

                        case SurfaceFormat.Dxt3:
                            numArray = DxtUtil.DecompressDxt3(numArray, width2, height2);
                            break;

                        case SurfaceFormat.Dxt5:
                            numArray = DxtUtil.DecompressDxt5(numArray, width2, height2);
                            break;
                        }
                    }
                    switch (surfaceFormat)
                    {
                    case SurfaceFormat.Bgra5551:
                        int startIndex1 = 0;
                        for (int index1 = 0; index1 < height2; ++index1)
                        {
                            for (int index2 = 0; index2 < width2; ++index2)
                            {
                                ushort num3 = BitConverter.ToUInt16(numArray, startIndex1);
                                ushort num4 = (ushort)(((int)num3 & (int)short.MaxValue) << 1 | ((int)num3 & 32768) >> 15);
                                numArray[startIndex1]     = (byte)num4;
                                numArray[startIndex1 + 1] = (byte)((uint)num4 >> 8);
                                startIndex1 += 2;
                            }
                        }
                        break;

                    case SurfaceFormat.Bgra4444:
                        int startIndex2 = 0;
                        for (int index1 = 0; index1 < height2; ++index1)
                        {
                            for (int index2 = 0; index2 < width2; ++index2)
                            {
                                ushort num3 = BitConverter.ToUInt16(numArray, startIndex2);
                                ushort num4 = (ushort)(((int)num3 & 4095) << 4 | ((int)num3 & 61440) >> 12);
                                numArray[startIndex2]     = (byte)num4;
                                numArray[startIndex2 + 1] = (byte)((uint)num4 >> 8);
                                startIndex2 += 2;
                            }
                        }
                        break;

                    case SurfaceFormat.NormalizedByte4:
                        int num5 = GraphicsExtensions.Size(surfaceFormat);
                        int num6 = width2 * num5;
                        for (int index1 = 0; index1 < height2; ++index1)
                        {
                            for (int index2 = 0; index2 < width2; ++index2)
                            {
                                int num3 = BitConverter.ToInt32(numArray, index1 * num6 + index2 * num5);
                                numArray[index1 * num6 + index2 * 4]     = (byte)(num3 >> 16 & (int)byte.MaxValue);
                                numArray[index1 * num6 + index2 * 4 + 1] = (byte)(num3 >> 8 & (int)byte.MaxValue);
                                numArray[index1 * num6 + index2 * 4 + 2] = (byte)(num3 & (int)byte.MaxValue);
                                numArray[index1 * num6 + index2 * 4 + 3] = (byte)(num3 >> 24 & (int)byte.MaxValue);
                            }
                        }
                        break;
                    }
                    texture2D.SetData <byte>(level, new Rectangle?(), numArray, 0, numArray.Length);
                }
            }
            return(texture2D);
        }
Пример #24
0
        /// <summary>
        /// Gets the raw pixel data for the texture.
        /// </summary>
        /// <returns>A byte array with the image data.</returns>
        private byte[] GetImageData(int layer = -1)
        {
            byte[] imageData = null;

            int layers = this.layers;

            if (layers == 0)
            {
                layers = 1;
            }

            switch (this.textureFormat)
            {
            case XivTexFormat.DXT1:
                imageData = DxtUtil.DecompressDxt1(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.DXT3:
                imageData = DxtUtil.DecompressDxt3(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.DXT5:
                imageData = DxtUtil.DecompressDxt5(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.A4R4G4B4:
                imageData = Read4444Image(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.A1R5G5B5:
                imageData = Read5551Image(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.A8R8G8B8:
                imageData = SwapRBColors(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.L8:
            case XivTexFormat.A8:
                imageData = Read8bitImage(this.rawData, this.width, this.height * layers);
                break;

            case XivTexFormat.X8R8G8B8:
            case XivTexFormat.R32F:
            case XivTexFormat.G16R16F:
            case XivTexFormat.G32R32F:
            case XivTexFormat.A16B16G16R16F:
            case XivTexFormat.A32B32G32R32F:
            case XivTexFormat.D16:
            default:
                imageData = this.rawData;
                break;
            }

            if (layer >= 0)
            {
                int bytesPerLayer = imageData.Length / this.layers;
                int offset        = bytesPerLayer * layer;

                byte[] nData = new byte[bytesPerLayer];
                Array.Copy(imageData, offset, nData, 0, bytesPerLayer);

                imageData = nData;
            }

            return(imageData);
        }
Пример #25
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormat_Legacy legacyFormat =
                    (SurfaceFormat_Legacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotSupportedException(
                              "Unsupported legacy surface format."
                              );
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }
            int           width            = reader.ReadInt32();
            int           height           = reader.ReadInt32();
            int           levelCount       = reader.ReadInt32();
            int           levelCountOutput = levelCount;
            SurfaceFormat convertedFormat  = surfaceFormat;

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1:
                if (!OpenGLDevice.Instance.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                if (!OpenGLDevice.Instance.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }
            if (existingInstance == null)
            {
                texture = new Texture2D(
                    reader.GraphicsDevice,
                    width,
                    height,
                    levelCountOutput > 1,
                    convertedFormat
                    );
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level += 1)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = null;      // Don't assign this quite yet...
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                if (level >= levelCountOutput)
                {
                    continue;
                }
                // Convert the image data if required
                switch (surfaceFormat)
                {
                case SurfaceFormat.Dxt1:
                    if (!OpenGLDevice.Instance.SupportsDxt1)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Dxt3:
                    if (!OpenGLDevice.Instance.SupportsS3tc)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Dxt5:
                    if (!OpenGLDevice.Instance.SupportsS3tc)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Bgr565:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                }
                break;

                case SurfaceFormat.Bgra5551:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            ushort pixel = BitConverter.ToUInt16(
                                levelData,
                                offset
                                );
                            pixel = (ushort)(
                                ((pixel & 0x7FFF) << 1) |
                                ((pixel & 0x8000) >> 15)
                                );
                            levelData[offset] =
                                (byte)(pixel);
                            levelData[offset + 1] =
                                (byte)(pixel >> 8);
                            offset += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            ushort pixel = BitConverter.ToUInt16(
                                levelData,
                                offset
                                );
                            pixel = (ushort)(
                                ((pixel & 0x0FFF) << 4) |
                                ((pixel & 0xF000) >> 12)
                                );
                            levelData[offset] =
                                (byte)(pixel);
                            levelData[offset + 1] =
                                (byte)(pixel >> 8);
                            offset += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    int bytesPerPixel = 4;                             // According to Texture.GetFormatSize()
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            int color = BitConverter.ToInt32(
                                levelData,
                                y * pitch + x * bytesPerPixel
                                );
                            // R:=W
                            levelData[y * pitch + x * 4] =
                                (byte)(((color >> 16) & 0xff));
                            // G:=V
                            levelData[y * pitch + x * 4 + 1] =
                                (byte)(((color >> 8) & 0xff));
                            // B:=U
                            levelData[y * pitch + x * 4 + 2] =
                                (byte)(((color) & 0xff));
                            // A:=Q
                            levelData[y * pitch + x * 4 + 3] =
                                (byte)(((color >> 24) & 0xff));
                        }
                    }
                }
                break;
                }

                if (levelData == null &&
                    reader.BaseStream.GetType() != typeof(System.IO.MemoryStream))
                {
                    /* If the ContentReader is not backed by a
                     * MemoryStream, we have to read the data in.
                     */
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                }
                if (levelData != null)
                {
                    /* If we had to convert the data, or get the data from a
                     * non-MemoryStream, we set the data with our levelData
                     * reference.
                     */
                    texture.SetData(level, null, levelData, 0, levelData.Length);
                }
                else
                {
                    /* Ideally, we didn't have to perform any conversion or
                     * unnecessary reading. Just throw the buffer directly
                     * into SetData, skipping a redundant byte[] copy.
                     */
                    texture.SetData <byte>(
                        level,
                        null,
                        (((System.IO.MemoryStream)(reader.BaseStream)).GetBuffer()),
                        (int)reader.BaseStream.Position,
                        levelDataSizeInBytes
                        );
                    reader.BaseStream.Seek(
                        levelDataSizeInBytes,
                        System.IO.SeekOrigin.Current
                        );
                }
            }

            return(texture);
        }
Пример #26
0
        public TextureToBitmap(byte[] decompressedData, int textureType, int[] dimensions)
        {
            byte[] decompressedTexture;

            switch (textureType)
            {
            //DXT1
            case 13344:
                typeString          = "DXT1";
                decompressedTexture = DxtUtil.DecompressDxt1(decompressedData, dimensions[0], dimensions[1]);
                bmp = readLinearImage(decompressedTexture, dimensions[0], dimensions[1]);
                break;

            //DXT3
            case 13360:
                typeString          = "DXT3";
                decompressedTexture = DxtUtil.DecompressDxt3(decompressedData, dimensions[0], dimensions[1]);
                bmp = readLinearImage(decompressedTexture, dimensions[0], dimensions[1]);
                break;

            //DXT5
            case 13361:
                typeString          = "DXT5";
                decompressedTexture = DxtUtil.DecompressDxt5(decompressedData, dimensions[0], dimensions[1]);
                bmp = readLinearImage(decompressedTexture, dimensions[0], dimensions[1]);
                break;

            //8-bit image
            case 4401:
            case 4400:
                typeString = "8bit";
                bmp        = read8bitImage(decompressedData, dimensions[0], dimensions[1]);
                break;

            //16-bit image in RGB4444 format
            case 5184:
                typeString = "16bit R4G4B4A4";
                bmp        = read4444Image(decompressedData, dimensions[0], dimensions[1]);
                break;

            //16-bit image in RGB5551 format
            case 5185:
                typeString = "16bit R5G5B5A1";
                bmp        = read5551Image(decompressedData, dimensions[0], dimensions[1]);
                break;

            //32-bit A8R8G8B8 image
            case 5200:
            case 4440:
            case 5201:
                typeString = "32bit A8R8G8B8";
                bmp        = new Bitmap(dimensions[0], dimensions[1], dimensions[0] * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, Marshal.UnsafeAddrOfPinnedArrayElement(decompressedData, 0));
                break;

            //64-bit A16R16G16B16 image
            case 9312:
                typeString = "64bit A16R16G16B16";
                bmp        = readRGBAFImage(decompressedData, dimensions[0], dimensions[1]);
                break;
            }
        }
Пример #27
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                /* These integer values are based on the enum values
                 * from previous XNA versions.
                 * -flibit
                 */
                int legacyFormat = reader.ReadInt32();
                if (legacyFormat == 1)
                {
                    surfaceFormat = SurfaceFormat.ColorBgraEXT;
                }
                else if (legacyFormat == 28)
                {
                    surfaceFormat = SurfaceFormat.Dxt1;
                }
                else if (legacyFormat == 30)
                {
                    surfaceFormat = SurfaceFormat.Dxt3;
                }
                else if (legacyFormat == 32)
                {
                    surfaceFormat = SurfaceFormat.Dxt5;
                }
                else
                {
                    throw new NotSupportedException(
                              "Unsupported legacy surface format."
                              );
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }
            int width            = reader.ReadInt32();
            int height           = reader.ReadInt32();
            int levelCount       = reader.ReadInt32();
            int levelCountOutput = levelCount;

            // Check to see if we need to convert the surface data
            SurfaceFormat convertedFormat = surfaceFormat;

            if (surfaceFormat == SurfaceFormat.Dxt1 &&
                !reader.GraphicsDevice.GLDevice.SupportsDxt1)
            {
                convertedFormat = SurfaceFormat.Color;
            }
            else if ((surfaceFormat == SurfaceFormat.Dxt3 ||
                      surfaceFormat == SurfaceFormat.Dxt5) &&
                     !reader.GraphicsDevice.GLDevice.SupportsS3tc)
            {
                convertedFormat = SurfaceFormat.Color;
            }

            // Check for duplicate instances
            if (existingInstance == null)
            {
                texture = new Texture2D(
                    reader.GraphicsDevice,
                    width,
                    height,
                    levelCountOutput > 1,
                    convertedFormat
                    );
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level += 1)
            {
                int    levelDataSizeInBytes = reader.ReadInt32();
                byte[] levelData            = null;      // Don't assign this quite yet...
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                if (level >= levelCountOutput)
                {
                    continue;
                }

                // Swap the image data if required.
                if (reader.platform == 'x')
                {
                    if (surfaceFormat == SurfaceFormat.Color ||
                        surfaceFormat == SurfaceFormat.ColorBgraEXT)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapColor(
                            levelData
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                }

                // Convert the image data if required
                if (surfaceFormat == SurfaceFormat.Dxt1 &&
                    !reader.GraphicsDevice.GLDevice.SupportsDxt1)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt1(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }
                else if (surfaceFormat == SurfaceFormat.Dxt3 &&
                         !reader.GraphicsDevice.GLDevice.SupportsS3tc)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt3(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }
                else if (surfaceFormat == SurfaceFormat.Dxt5 &&
                         !reader.GraphicsDevice.GLDevice.SupportsS3tc)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt5(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }

                if (levelData == null &&
                    reader.BaseStream.GetType() != typeof(System.IO.MemoryStream))
                {
                    /* If the ContentReader is not backed by a
                     * MemoryStream, we have to read the data in.
                     */
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                }
                if (levelData != null)
                {
                    /* If we had to convert the data, or get the data from a
                     * non-MemoryStream, we set the data with our levelData
                     * reference.
                     */
                    texture.SetData(level, null, levelData, 0, levelData.Length);
                }
                else
                {
                    /* Ideally, we didn't have to perform any conversion or
                     * unnecessary reading. Just throw the buffer directly
                     * into SetData, skipping a redundant byte[] copy.
                     */
                    texture.SetData <byte>(
                        level,
                        null,
                        (((System.IO.MemoryStream)(reader.BaseStream)).GetBuffer()),
                        (int)reader.BaseStream.Position,
                        levelDataSizeInBytes
                        );
                    reader.BaseStream.Seek(
                        levelDataSizeInBytes,
                        System.IO.SeekOrigin.Current
                        );
                }
            }

            return(texture);
        }
Пример #28
0
        public static byte[] ExtractImageCore(BinaryReader reader, RectInfo?rectInfoList = null)
        {
            var magic             = Encoding.ASCII.GetString(reader.ReadBytes(4));
            var endianCheck1      = reader.ReadInt32();
            var endianCheck2      = reader.ReadInt32();
            var requiresEndianFix = endianCheck2 == 0x00010100;

            reader.BaseStream.Seek(0x0c, SeekOrigin.Begin);

            var dataSize = ReadInt32(reader, requiresEndianFix) - 0x40;
            var width    = ReadInt16(reader, requiresEndianFix);
            var height   = ReadInt16(reader, requiresEndianFix);

            if (!requiresEndianFix)
            {
                reader.BaseStream.Seek(0x03, SeekOrigin.Current);
            }


            /*
             *  GRAYSCALE_FORMAT 0x01
             *  GRAYSCALE_FORMAT_2 0x06
             *  BGR_16BIT_FORMAT 0x0C
             *  BGRA_16BIT_FORMAT 0x0D
             *  BGR_FORMAT 0x0E
             *  BGRA_FORMAT 0x10
             *  BGR_4BIT_FORMAT 0x11
             *  BGR_8BIT_FORMAT 0x12
             *  DXT1_FORMAT 0x16
             *  DXT3_FORMAT 0x18
             *  DXT5_FORMAT 0x1A
             */

            var dataFormat = reader.ReadByte();

            reader.BaseStream.Seek(0x40, SeekOrigin.Begin);
            var bitmapData = reader.ReadBytes(dataSize);

            var paletteEntries = new List <Color>();

            var pixelFormat = PixelFormat.Undefined;

            if (dataFormat == 0x01)
            {
                // GRAYSCALE_FORMAT8
                pixelFormat = PixelFormat.Format8bppIndexed;
            }
            else if (dataFormat == 0x06)
            {
                // GRAYSCALE_FORMAT_2
                pixelFormat = PixelFormat.Format8bppIndexed;
            }
            else if (dataFormat == 0x0c)
            {
                // BGR_16BIT_FORMAT
                pixelFormat = PixelFormat.Format16bppRgb565;
            }
            else if (dataFormat == 0x0d)
            {
                // BGRA_16BIT_FORMAT
                byte[] newBitmapData = new byte[width * height * 4];
                for (int didx = 0, i = 0; i < height; i++)
                {
                    for (var j = 0; j < width; j++, didx += 2)
                    {
                        ushort c = (ushort)((bitmapData[didx + 1] << 8) | bitmapData[didx]);

                        DxtUtil.ConvertArgb4444ToArgb8888(c, out var a, out var r, out var g, out var b);

                        newBitmapData[(j * 4) + (i * width * 4)]     = a;
                        newBitmapData[(j * 4) + 1 + (i * width * 4)] = r;
                        newBitmapData[(j * 4) + 2 + (i * width * 4)] = g;
                        newBitmapData[(j * 4) + 3 + (i * width * 4)] = b;
                    }
                }

                bitmapData = newBitmapData;

                pixelFormat = PixelFormat.Format32bppArgb;
            }
            else if (dataFormat == 0x0e)
            {
                // BGR_FORMAT
                pixelFormat = PixelFormat.Format24bppRgb;
            }
            else if (dataFormat == 0x10)
            {
                // BGRA_FORMAT
                pixelFormat = PixelFormat.Format32bppArgb;
            }
            else if (dataFormat == 0x11)
            {
                // BGR_4BIT_FORMAT
                var bitmapDataOnly = new byte[width * height / 2];
                Buffer.BlockCopy(bitmapData, 0, bitmapDataOnly, 0, bitmapDataOnly.Length);

                var paletteData = new byte[bitmapData.Length - bitmapDataOnly.Length - 0x14]; // Skip palette header
                Buffer.BlockCopy(bitmapData, bitmapDataOnly.Length + 0x14, paletteData, 0, paletteData.Length);

                bitmapData = bitmapDataOnly;

                pixelFormat = PixelFormat.Format4bppIndexed;

                for (int i = 0; i < paletteData.Length; i += 4)
                {
                    paletteEntries.Add(Color.FromArgb(paletteData[i + 3], paletteData[i], paletteData[i + 1], paletteData[i + 2]));
                }

                // Flip pixels
                for (int i = 0; i < bitmapData.Length; i++)
                {
                    var l = (bitmapData[i] & 0x0f) << 4;
                    var r = (bitmapData[i] & 0xf0) >> 4;
                    bitmapData[i] = (byte)(l | r);
                }
            }
            else if (dataFormat == 0x12)
            {
                // BGR_8BIT_FORMAT
                var bitmapDataOnly = new byte[width * height];
                Buffer.BlockCopy(bitmapData, 0, bitmapDataOnly, 0, bitmapDataOnly.Length);

                var paletteData = new byte[bitmapData.Length - bitmapDataOnly.Length - 0x14]; // Skip palette header
                Buffer.BlockCopy(bitmapData, bitmapDataOnly.Length + 0x14, paletteData, 0, paletteData.Length);

                bitmapData = bitmapDataOnly;

                pixelFormat = PixelFormat.Format8bppIndexed;

                for (int i = 0; i < paletteData.Length; i += 4)
                {
                    paletteEntries.Add(Color.FromArgb(paletteData[i + 3], paletteData[i], paletteData[i + 1], paletteData[i + 2]));
                }
            }
            else if (dataFormat == 0x16)
            {
                // DXT1_FORMAT
                pixelFormat = PixelFormat.Format32bppArgb;
                bitmapData  = DxtUtil.DecompressDxt1(bitmapData, width, height);
            }
            else if (dataFormat == 0x18)
            {
                // DXT3_FORMAT
                pixelFormat = PixelFormat.Format32bppArgb;
                bitmapData  = DxtUtil.DecompressDxt3(bitmapData, width, height);
            }
            else if (dataFormat == 0x1a)
            {
                // DXT5_FORMAT
                pixelFormat = PixelFormat.Format32bppArgb;
                bitmapData  = DxtUtil.DecompressDxt5(bitmapData, width, height);
            }
            else
            {
                throw new Exception(String.Format("Found unknown pixel format: {0:x2}", dataFormat));
            }

            for (int i = 0; i < bitmapData.Length;)
            {
                if (pixelFormat == PixelFormat.Format16bppArgb1555)
                {
                    var a = bitmapData[i] & 0x0f;
                    var r = (bitmapData[i] >> 4) & 0x0f;
                    var g = bitmapData[i + 1] & 0x0f;
                    var b = (bitmapData[i + 1] >> 4) & 0x0f;

                    bitmapData[i + 1] = (byte)((a << 4) | b);
                    bitmapData[i + 0] = (byte)((g << 4) | r);

                    i += 2;
                }
                else if (pixelFormat == PixelFormat.Format16bppRgb565)
                {
                    bitmapData[i] = (byte)((bitmapData[i] & 0xc0) | (bitmapData[i] & 0x3f) >> 1);
                    i            += 2;
                }
                else if (pixelFormat == PixelFormat.Format24bppRgb)
                {
                    var t = bitmapData[i + 2];
                    bitmapData[i + 2] = bitmapData[i];
                    bitmapData[i]     = t;
                    i += 3;
                }
                else if (pixelFormat == PixelFormat.Format32bppArgb)
                {
                    var t = bitmapData[i + 2];
                    bitmapData[i + 2] = bitmapData[i];
                    bitmapData[i]     = t;
                    i += 4;
                }
                else
                {
                    break;
                }
            }

            if (pixelFormat == PixelFormat.Undefined ||
                pixelFormat == PixelFormat.Format16bppArgb1555)
            {
                // Create DDS file
                var output = new List <byte>();

                output.AddRange(new byte[]
                {
                    0x44, 0x44, 0x53, 0x20, 0x7C, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00
                });

                output.AddRange(BitConverter.GetBytes(height));
                output.AddRange(BitConverter.GetBytes(width));
                output.AddRange(BitConverter.GetBytes(dataSize));

                output.AddRange(new byte[]
                {
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
                });

                if (pixelFormat == PixelFormat.Format16bppArgb1555)
                {
                    output.AddRange(new byte[]
                    {
                        0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00,
                        0xF0, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    });
                }
                else if (pixelFormat == PixelFormat.Format16bppRgb555)
                {
                    output.AddRange(new byte[]
                    {
                        0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00,
                        0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    });
                }
                else
                {
                    output.AddRange(new byte[]
                    {
                        0x04, 0x00, 0x00, 0x00
                    });

                    if (dataFormat == 0x16)
                    {
                        output.AddRange(Encoding.ASCII.GetBytes("DXT1"));
                    }
                    else if (dataFormat == 0x18)
                    {
                        output.AddRange(Encoding.ASCII.GetBytes("DXT3"));
                    }
                    else if (dataFormat == 0x1a)
                    {
                        output.AddRange(Encoding.ASCII.GetBytes("DXT5"));
                    }

                    output.AddRange(new byte[]
                    {
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    });
                }

                output.AddRange(bitmapData);

                return(output.ToArray());
            }
            else
            {
                var b = new Bitmap(width, height, pixelFormat);

                if (pixelFormat == PixelFormat.Format8bppIndexed || pixelFormat == PixelFormat.Format4bppIndexed)
                {
                    ColorPalette palette = b.Palette;
                    Color[]      entries = palette.Entries;

                    if (paletteEntries.Count == 0)
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            Color c = Color.FromArgb((byte)i, (byte)i, (byte)i);
                            entries[i] = c;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < paletteEntries.Count; i++)
                        {
                            entries[i] = paletteEntries[i];
                        }
                    }

                    b.Palette = palette;
                }

                var        boundsRect = new Rectangle(0, 0, width, height);
                BitmapData bmpData    = b.LockBits(boundsRect,
                                                   ImageLockMode.WriteOnly,
                                                   b.PixelFormat);

                IntPtr ptr = bmpData.Scan0;

                if (pixelFormat != PixelFormat.Format24bppRgb)
                {
                    int bytes = bmpData.Stride * b.Height;
                    Marshal.Copy(bitmapData, 0, ptr, bytes);
                }
                else
                {
                    // Because things are stupid, we have to pad the lines for 24bit images ourself...
                    for (int i = 0; i < height; i++)
                    {
                        Marshal.Copy(bitmapData, i * width * 3, ptr + (bmpData.Stride * i), width * 3);
                    }
                }

                b.UnlockBits(bmpData);

                // Split into separate smaller bitmap
                if (rectInfoList != null)
                {
                    var    rect     = new Rectangle(rectInfoList.Value.X, rectInfoList.Value.Y, rectInfoList.Value.W, rectInfoList.Value.H);
                    Bitmap subimage = new Bitmap(rect.Width, rect.Height);

                    Console.WriteLine(rect);

                    using (Graphics g = Graphics.FromImage(subimage))
                    {
                        g.DrawImage(b, new Rectangle(0, 0, subimage.Width, subimage.Height), rect, GraphicsUnit.Pixel);
                    }

                    b = subimage;
                }

                ImageConverter converter = new ImageConverter();
                return((byte[])converter.ConvertTo(b, typeof(byte[])));
            }
        }