private unsafe void CalculateMipInfosNoncompressed(int mipCount, int pitch, out int chainSize) { if (mipCount == -1) { mipCount = 1; } int bytesPerPixel = Helper.FormatBits(this.DxgiFormat, this.D3DFormat) / 8; if (pitch == -1) { pitch = this.Width * bytesPerPixel; if ((pitch & 0x3) != 0) { pitch += 4 - (pitch & 0x3); } } this.MipInfos = new ImageMipInfo[mipCount]; fixed(ImageMipInfo *infos = this.MipInfos) { infos[0] = new ImageMipInfo { Width = this.Width, Height = this.Height, Depth = this.Depth, OffsetInBytes = 0, SizeInBytes = pitch * this.Height * this.Depth, }; for (int i = 1; i < mipCount; i++) { infos[i] = new ImageMipInfo { Width = Math.Max(1, infos[i - 1].Width / 2), Height = Math.Max(1, infos[i - 1].Height / 2), Depth = Math.Max(1, infos[i - 1].Depth / 2), OffsetInBytes = infos[i - 1].OffsetInBytes + infos[i - 1].SizeInBytes, }; int mipPitch = infos[i].Width * bytesPerPixel; if ((mipPitch & 0x3) != 0) { mipPitch += 4 - (mipPitch & 0x3); } infos[i].SizeInBytes = mipPitch * infos[i].Height * infos[i].Depth; } chainSize = infos[mipCount - 1].OffsetInBytes + infos[mipCount - 1].SizeInBytes; } }
/// <summary> /// Decode BMP Header. /// </summary> /// <param name="reader">Binary reader.</param> /// <param name="databoxes">Databoxes array.</param> /// <param name="description">Image Description.</param> public unsafe void DecodeData(BinaryReader reader, out DataBox[] databoxes, out ImageDescription description) { reader.BaseStream.Seek(0, SeekOrigin.Begin); byte[] bytes = reader.ReadBytes((int)reader.BaseStream.Length); DdsTexture dds = new DdsTexture(bytes); uint faces = 1; if (dds.MiscFlags10.HasFlag(ResourceMiscFlags.TextureCube)) { faces = 6; } description = new ImageDescription() { imageFormat = ImageFormat.DDS, Width = (uint)dds.Width, Height = (uint)dds.Height, Depth = (uint)dds.Depth, MipLevels = (uint)dds.MipInfos.Length, ArraySize = (uint)dds.Data.Length / faces, Faces = faces, pixelFormat = (WaveEngine.Common.Graphics.PixelFormat)dds.DxgiFormat, }; databoxes = new DataBox[description.ArraySize * description.Faces * description.MipLevels]; for (uint i = 0; i < description.ArraySize; i++) { for (uint j = 0; j < description.Faces; j++) { byte[] data = dds.Data[(i * description.Faces) + j]; GCHandle pinnedHandle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr dataPointer = Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); for (uint z = 0; z < description.MipLevels; z++) { ImageMipInfo mipInfo = dds.MipInfos[z]; uint slicePitch = (uint)mipInfo.SizeInBytes; uint rowPitch = slicePitch / (uint)mipInfo.Height; uint index = (i * description.Faces) + (j * description.MipLevels) + z; databoxes[index] = new DataBox(IntPtr.Add(dataPointer, (int)mipInfo.OffsetInBytes), rowPitch, slicePitch); } pinnedHandle.Free(); } } }
private unsafe void CalculateMipInfosCompressed(int mipCount, int linearSize, out int chainSize) { if (mipCount == -1) { mipCount = 1; } int multiplyer = this.DxgiFormat == DxgiFormat.BC1_TYPELESS || this.DxgiFormat == DxgiFormat.BC1_UNORM || this.DxgiFormat == DxgiFormat.BC1_UNORM_SRGB || this.D3DFormat == D3DFormat.Dxt1 ? 8 : 16; ////if (linearSize == -1) ////{ linearSize = Math.Max(1, this.Width / 4) * Math.Max(1, this.Height / 4) * this.Depth * multiplyer; ////} this.MipInfos = new ImageMipInfo[mipCount]; fixed(ImageMipInfo *infos = this.MipInfos) { infos[0] = new ImageMipInfo { Width = this.Width, Height = this.Height, Depth = this.Depth, OffsetInBytes = 0, SizeInBytes = linearSize, }; for (int i = 1; i < mipCount; i++) { infos[i] = new ImageMipInfo { Width = Math.Max(1, infos[i - 1].Width / 2), Height = Math.Max(1, infos[i - 1].Height / 2), Depth = Math.Max(1, infos[i - 1].Depth / 2), OffsetInBytes = infos[i - 1].OffsetInBytes + infos[i - 1].SizeInBytes, }; infos[i].SizeInBytes = Math.Max(1, infos[i].Width / 4) * Math.Max(1, infos[i].Height / 4) * infos[i].Depth * multiplyer; } chainSize = infos[mipCount - 1].OffsetInBytes + infos[mipCount - 1].SizeInBytes; } }