public void Export(Stream stream) { BinaryWriter writer = new BinaryWriter(stream); byte[] buffer = null; switch (m_TextureFormat) { case TextureFormat.DXT1: case TextureFormat.DXT5: byte[] dds_header = DDS.CreateHeader(m_Width, m_Height, 32, m_MipMap ? 2 : 0, m_TextureFormat); writer.Write(dds_header); buffer = image_data; break; case TextureFormat.RGB24: byte[] tga_header = TGA.CreateHeader((ushort)m_Width, (ushort)m_Height, 24); writer.Write(tga_header); buffer = new byte[image_data.Length]; for (int i = 0, j = 2; j < m_CompleteImageSize; i += 3, j += 3) { byte b = image_data[j]; buffer[j] = image_data[i]; buffer[i] = b; buffer[i + 1] = image_data[i + 1]; } break; case TextureFormat.ARGB32: tga_header = TGA.CreateHeader((ushort)m_Width, (ushort)m_Height, 32); writer.Write(tga_header); buffer = new byte[image_data.Length]; for (int i = 0, j = 3, k = 1, l = 2; j < m_CompleteImageSize; i += 4, j += 4, k += 4, l += 4) { byte b = image_data[j]; buffer[j] = image_data[i]; buffer[i] = b; b = image_data[l]; buffer[l] = image_data[k]; buffer[k] = b; } break; case TextureFormat.Alpha8: tga_header = TGA.CreateHeader((ushort)m_Width, (ushort)m_Height, 8); writer.Write(tga_header); buffer = (byte[])image_data.Clone(); break; case TextureFormat.RGBA32: tga_header = TGA.CreateHeader((ushort)m_Width, (ushort)m_Height, 32); writer.Write(tga_header); buffer = (byte[])image_data.Clone(); break; default: throw new Exception("Unhandled Texture2D format: " + m_TextureFormat); } writer.Write(buffer); }
public static Texture2D ToImage(ImportedTexture tex, ImageLoadInformation loadInfo, out byte pixelDepth) { ushort width, height; byte[] data; using (Stream stream = new MemoryStream(tex.Data)) { byte idLen, descriptor; bool compressed; short originY; GetImageInfo(stream, out idLen, out compressed, out originY, out width, out height, out pixelDepth, out descriptor); if (compressed) { throw new Exception("Warning! Compressed TGAs are not supported"); } stream.Position = idLen + 0x12; BinaryReader reader = new BinaryReader(stream); data = reader.ReadToEnd(); if (originY == 0) { Flip((short)height, width, height, (byte)(pixelDepth >> 3), data); } } byte[] header = DDS.CreateHeader(width, height, pixelDepth, 0, false, pixelDepth == 32 ? DDS.UnityCompatibleFormat.ARGB32 : DDS.UnityCompatibleFormat.RGB24); using (BinaryWriter writer = new BinaryWriter(new MemoryStream())) { writer.Write(header); writer.Write(data); try { writer.BaseStream.Position = 0; return(Texture2D.FromStream(Gui.Renderer.Device, writer.BaseStream, (int)writer.BaseStream.Length, loadInfo)); } catch (Exception e) { Direct3D11Exception d3de = e as Direct3D11Exception; if (d3de != null) { Report.ReportLog("Direct3D11 Exception name=\"" + d3de.ResultCode.Name + "\" desc=\"" + d3de.ResultCode.Description + "\" code=0x" + ((uint)d3de.ResultCode.Code).ToString("X")); } else { Utility.ReportException(e); } return(null); } } }
public void Export(Stream stream) { BinaryWriter writer = new BinaryWriter(stream); byte[] buffer = null; switch (m_TextureFormat) { case TextureFormat.DXT1: case TextureFormat.DXT5: byte[] dds_header = DDS.CreateHeader(m_Width, m_Height, 32, m_MipMap ? 2 : 0, m_TextureFormat == TextureFormat.DXT1 ? (byte)'D' | ((byte)'X' << 8) | ((byte)'T' << 16) | ((byte)'1' << 24) : (byte)'D' | ((byte)'X' << 8) | ((byte)'T' << 16) | ((byte)'5' << 24)); writer.Write(dds_header); buffer = image_data; break; case TextureFormat.RGB24: byte[] tga_header = new byte[0x12] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)m_Width, (byte)(m_Width >> 8), (byte)m_Height, (byte)(m_Height >> 8), 24, 0 }; writer.Write(tga_header); buffer = new byte[image_data.Length]; for (int i = 0, j = 2; j < m_CompleteImageSize; i += 3, j += 3) { byte b = image_data[j]; buffer[j] = image_data[i]; buffer[i] = b; buffer[i + 1] = image_data[i + 1]; } break; case TextureFormat.ARGB32: tga_header = new byte[0x12] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)m_Width, (byte)(m_Width >> 8), (byte)m_Height, (byte)(m_Height >> 8), 32, 0 }; writer.Write(tga_header); buffer = new byte[image_data.Length]; for (int i = 0, j = 3, k = 1, l = 2; j < m_CompleteImageSize; i += 4, j += 4, k += 4, l += 4) { byte b = image_data[j]; buffer[j] = image_data[i]; buffer[i] = b; b = image_data[l]; buffer[l] = image_data[k]; buffer[k] = b; } break; case TextureFormat.Alpha8: tga_header = new byte[0x12] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte)m_Width, (byte)(m_Width >> 8), (byte)m_Height, (byte)(m_Height >> 8), 8, 0 }; writer.Write(tga_header); buffer = (byte[])image_data.Clone(); break; default: throw new Exception("Unhandled Texture2D format: " + m_TextureFormat); } writer.Write(buffer); }
public static Texture2D ScaleWhenNeeded(byte[] file_data, out int originalWidth, out int originalHeight, out int BPP, out bool cubemap) { uint[] fileHeader; int mipmaps; uint pixelFormat; uint fourCC; UnityCompatibleFormat format; uint[] dx10Header = null; using (BinaryReader reader = new BinaryReader(new MemoryStream(file_data))) { fileHeader = reader.ReadUInt32Array(32); originalWidth = (int)fileHeader[4]; originalHeight = (int)fileHeader[3]; mipmaps = (int)fileHeader[7]; pixelFormat = fileHeader[20]; fourCC = fileHeader[21]; if ((pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_FOURCC) != 0 && fourCC == FOURCC_DX10) { dx10Header = reader.ReadUInt32Array(5); fourCC = dx10Header[0]; } format = (pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_FOURCC) != 0 ? fourCC == FOURCC_DXT1 ? UnityCompatibleFormat.DXT1 : fourCC == FOURCC_DXT5 ? UnityCompatibleFormat.DXT5 : fourCC == (uint)SlimDX.Direct3D9.Format.A32B32G32R32F ? UnityCompatibleFormat.RGBAFloat : fourCC == (uint)SlimDX.Direct3D9.Format.A16B16G16R16F ? UnityCompatibleFormat.RGBAHalf : fourCC == (uint)SlimDX.DXGI.Format.BC7_UNorm ? UnityCompatibleFormat.BC7 : (UnityCompatibleFormat)(-1) : (pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_ALPHAPIXELS) != 0 ? UnityCompatibleFormat.ARGB32 : UnityCompatibleFormat.RGB24; cubemap = fileHeader[28] == (uint)(DDS_CAPS2.DDSCAPS2_CUBEMAP | DDS_CAPS2.DDS_CUBEMAP_ALLFACES); } if (format == (UnityCompatibleFormat)(-1)) { throw new Exception("Unsupported DDS format - FourCC x" + fourCC.ToString("X")); } if ((format == UnityCompatibleFormat.ARGB32 || format == UnityCompatibleFormat.RGB24) && (fileHeader[23] != 0x00ff0000 || fileHeader[24] != 0x0000ff00 || fileHeader[25] != 0x000000ff)) { throw new Exception("Unsupported DDS channel order or usage"); } if (format == UnityCompatibleFormat.RGB24 && fileHeader[26] != 0 || format == UnityCompatibleFormat.ARGB32 && fileHeader[26] != 0xff000000) { Report.ReportLog("Warning! Wrong DDS channel order or usage"); } switch (format) { case UnityCompatibleFormat.RGB24: BPP = 24; break; case UnityCompatibleFormat.RGBAHalf: BPP = 64; break; case UnityCompatibleFormat.RGBAFloat: BPP = 128; break; default: BPP = 32; break; } byte[] buffer; int maxDim = cubemap ? 256 : 1024; if (originalWidth > maxDim || originalHeight > maxDim || cubemap) { int divSize = (pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_FOURCC) != 0 && (fourCC == FOURCC_DXT1 || fourCC == FOURCC_DXT5) ? 4 : 1; int blockBytes = (pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_FOURCC) != 0 ? format == UnityCompatibleFormat.DXT1 || format == UnityCompatibleFormat.RGBAHalf ? 8 : format == UnityCompatibleFormat.DXT5 || format == UnityCompatibleFormat.RGBAFloat ? 16 : -1 : (pixelFormat & (uint)DDS_PIXEL_FORMAT.DDPF_ALPHAPIXELS) != 0 ? 4 : 3; if (blockBytes <= 0) { buffer = file_data; } else { int src = fileHeader.Length * sizeof(uint) + (dx10Header != null ? dx10Header.Length * sizeof(uint) : 0); int dst = 0; buffer = null; int imgSize = (file_data.Length - src) / (cubemap ? 6 : 1); int srcBlockWidth = Math.Max(divSize, (originalWidth + divSize - 1)) / divSize; for (int i = 0; i < (cubemap ? 6 : 1); i++) { int width = originalWidth, blockWidth; int height = originalHeight, blockHeight; int blocks; int mipStart = src; int shift = 0; while (width > maxDim || height > maxDim) { blockWidth = Math.Max(divSize, (width + divSize - 1)) / divSize; blockHeight = Math.Max(divSize, (height + divSize - 1)) / divSize; blocks = blockWidth * blockHeight; mipStart += blocks * blockBytes; if (width > 1) { width >>= 1; } if (height > 1) { height >>= 1; } shift++; } blockWidth = Math.Max(divSize, (width + divSize - 1)) / divSize; blockHeight = Math.Max(divSize, (height + divSize - 1)) / divSize; blocks = blockWidth * blockHeight; int size = blocks * blockBytes; if (i == 0) { byte[] header = DDS.CreateHeader(width, height * (cubemap ? 6 : 1), BPP, 0, false, format); buffer = new byte[header.Length + size * (cubemap ? 6 : 1)]; Array.Copy(header, buffer, header.Length); dst = header.Length; } if (mipmaps <= 1) { int imgSrc = src; int srcLineRest = srcBlockWidth * blockBytes - (blockBytes << shift) * blockWidth; for (int y = 0; y < blockHeight; y++) { for (int x = 0; x < blockWidth; x++) { Array.Copy(file_data, imgSrc, buffer, dst, blockBytes); imgSrc += blockBytes << shift; dst += blockBytes; } imgSrc += srcLineRest + ((1 << shift) - 1) * srcBlockWidth * blockBytes; } } else { Array.Copy(file_data, mipStart, buffer, dst, size); dst += size; } src += imgSize; } } } else { buffer = file_data; } ImageLoadInformation loadInfo = new ImageLoadInformation() { BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, FilterFlags = FilterFlags.None, Format = Format.R8G8B8A8_UNorm, MipFilterFlags = FilterFlags.None, MipLevels = 0, OptionFlags = ResourceOptionFlags.None, Usage = ResourceUsage.Staging, }; return(Texture2D.FromMemory(Gui.Renderer.Device, buffer, loadInfo)); }