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); }
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); }