/// <summary> /// Turn raw BGRA8888 bytes to a Color array that can be used in a Texture2D. /// </summary> /// <param name="data">Raw image byte data</param> /// <param name="width">Expected width of the image</param> /// <param name="height">Expected height of the image</param> /// <returns>Pixel color data</returns> public static Color[] DecompressBGRA8888(Stream data, ushort width, ushort height) { Color[] texture2DColors = new Color[width * height]; bool exceededArray = false; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { byte blue = DataParser.ReadByte(data); byte green = DataParser.ReadByte(data); byte red = DataParser.ReadByte(data); byte alpha = DataParser.ReadByte(data); int flattenedIndex = row * width + col; if (flattenedIndex < texture2DColors.Length) { texture2DColors[flattenedIndex] = new Color(((float)red) / byte.MaxValue, ((float)green) / byte.MaxValue, ((float)blue) / byte.MaxValue, ((float)alpha) / byte.MaxValue); } else { Debug.LogError("BGRA8888: Exceeded expected texture size"); exceededArray = true; break; } } if (exceededArray) { break; } } return(texture2DColors); }
public const int DDS_DX10 = 808540228; //From "DX10" public static Texture2D LoadDDSFile(Stream data) { Texture2D texture = null; Color[] imageColors = null; DDS_HEADER header = new DDS_HEADER(); DDS_HEADER_10 header_10 = new DDS_HEADER_10(); int magic = DataParser.ReadInt(data); if (magic == DDS_) { header.dwSize = DataParser.ReadInt(data); //0 + 4 = 4 header.dwFlags = (DWFlags)DataParser.ReadInt(data); //4 + 4 = 8 header.dwHeight = DataParser.ReadInt(data); //8 + 4 = 12 header.dwWidth = DataParser.ReadInt(data); //12 + 4 = 16 header.dwPitchOrLinearSize = DataParser.ReadInt(data); //16 + 4 = 20 header.dwDepth = DataParser.ReadInt(data); //20 + 4 = 24 header.dwMipMapCount = DataParser.ReadInt(data); //24 + 4 = 28 header.dwReserved1 = new int[11]; //28 + 44 = 72 for (int i = 0; i < header.dwReserved1.Length; i++) { header.dwReserved1[i] = DataParser.ReadInt(data); } header.ddspf.dwSize = DataParser.ReadInt(data); //72 + 4 = 76 header.ddspf.dwFlags = (PIXELFORMAT_DWFlags)DataParser.ReadInt(data); //76 + 4 = 80 header.ddspf.dwFourCC = DataParser.ReadInt(data); //80 + 4 = 84 header.ddspf.dwRGBBitCount = DataParser.ReadInt(data); //84 + 4 = 88 header.ddspf.dwRBitMask = DataParser.ReadInt(data); //88 + 4 = 92 header.ddspf.dwGBitMask = DataParser.ReadInt(data); //92 + 4 = 96 header.ddspf.dwBBitMask = DataParser.ReadInt(data); //96 + 4 = 100 header.ddspf.dwABitMask = DataParser.ReadInt(data); //100 + 4 = 104 header.dwCaps = DataParser.ReadInt(data); //104 + 4 = 108 header.dwCaps2 = DataParser.ReadInt(data); //108 + 4 = 112 header.dwCaps3 = DataParser.ReadInt(data); //112 + 4 = 116 header.dwCaps4 = DataParser.ReadInt(data); //116 + 4 = 120 header.dwReserved2 = DataParser.ReadInt(data); //120 + 4 = 124 bool isCompressed = (header.ddspf.dwFlags & PIXELFORMAT_DWFlags.DDPF_FOURCC) != 0; if (isCompressed && header.ddspf.dwFourCC == DDS_DX10) { Debug.Log(nameof(DDSLoader) + ": Reading extra header"); header_10.dxgiFormat = (DXGI_FORMAT)DataParser.ReadInt(data); header_10.resourceDimension = (D3D10_RESOURCE_DIMENSION)DataParser.ReadInt(data); header_10.miscFlag = DataParser.ReadUInt(data); header_10.arraySize = DataParser.ReadUInt(data); header_10.miscFlags2 = DataParser.ReadUInt(data); } imageColors = Texture2DHelpers.DecompressRawBytes(data, (ushort)header.dwWidth, (ushort)header.dwHeight, GetDDSFormat(header)); Texture2DHelpers.FlipVertical(imageColors, (ushort)header.dwWidth, (ushort)header.dwHeight); } else { Debug.LogError(nameof(DDSLoader) + ": Invalid DDS magic, expected " + DDS_ + " got " + magic); } if (imageColors != null) { texture = new Texture2D(header.dwWidth, header.dwHeight); if (imageColors != null) { texture.SetPixels(imageColors); } texture.Apply(); } return(texture); }
/// <summary> /// Turn raw DXT5 bytes to a Color array that can be used in a Texture2D. /// </summary> /// <param name="data">Raw image byte data</param> /// <param name="width">Expected width of the image</param> /// <param name="height">Expected height of the image</param> /// <returns>Pixel color data</returns> public static Color[] DecompressDXT5(Stream data, ushort width, ushort height) { Color[] texture2DColors = new Color[width * height]; for (int row = 0; row < height; row += 4) { for (int col = 0; col < width; col += 4) { #region Alpha Information byte alpha0Data = 0; byte alpha1Data = 0; uint alphamask = 0; alpha0Data = DataParser.ReadByte(data); alpha1Data = DataParser.ReadByte(data); byte[] amdata = new byte[6]; data.Read(amdata, 0, amdata.Length); alphamask = BitConverter.ToUInt32(amdata, 0); float[] alphaPalette = new float[] { alpha0Data / 255f, alpha1Data / 255f, ((6 * alpha0Data + 1 * alpha1Data + 3) / 7) / 255f, ((5 * alpha0Data + 2 * alpha1Data + 3) / 7) / 255f, ((4 * alpha0Data + 3 * alpha1Data + 3) / 7) / 255f, ((3 * alpha0Data + 4 * alpha1Data + 3) / 7) / 255f, ((2 * alpha0Data + 5 * alpha1Data + 3) / 7) / 255f, ((1 * alpha0Data + 6 * alpha1Data + 3) / 7) / 255f }; if (alpha0Data <= alpha1Data) { alphaPalette[2] = (4 * alpha0Data + 1 * alpha1Data + 2) / 5; alphaPalette[3] = (3 * alpha0Data + 2 * alpha1Data + 2) / 5; alphaPalette[4] = (2 * alpha0Data + 3 * alpha1Data + 2) / 5; alphaPalette[5] = (1 * alpha0Data + 4 * alpha1Data + 2) / 5; alphaPalette[6] = 0; alphaPalette[7] = 1; } #endregion #region Color Information ushort color0Data = 0; ushort color1Data = 0; uint bitmask = 0; color0Data = DataParser.ReadUShort(data); color1Data = DataParser.ReadUShort(data); bitmask = DataParser.ReadUInt(data); int[] colors0 = new int[] { ((color0Data >> 11) & 0x1F) << 3, ((color0Data >> 5) & 0x3F) << 2, (color0Data & 0x1F) << 3 }; int[] colors1 = new int[] { ((color1Data >> 11) & 0x1F) << 3, ((color1Data >> 5) & 0x3F) << 2, (color1Data & 0x1F) << 3 }; Color[] colorPalette = new Color[] { new Color(colors0[0] / 255f, colors0[1] / 255f, colors0[2] / 255f), new Color(colors1[0] / 255f, colors1[1] / 255f, colors1[2] / 255f), new Color(((colors0[0] * 2 + colors1[0] + 1) / 3) / 255f, ((colors0[1] * 2 + colors1[1] + 1) / 3) / 255f, ((colors0[2] * 2 + colors1[2] + 1) / 3) / 255f), new Color(((colors1[0] * 2 + colors0[0] + 1) / 3) / 255f, ((colors1[1] * 2 + colors0[1] + 1) / 3) / 255f, ((colors1[2] * 2 + colors0[2] + 1) / 3) / 255f) }; #endregion #region Place All Information int blockIndex = 0; uint alphaBlockIndex1 = alphamask & 0x07, alphaBlockIndex2 = alphamask & 0x38; for (int blockY = 0; blockY < 4; blockY++) { for (int blockX = 0; blockX < 4; blockX++) { Color colorInBlock = colorPalette[(bitmask & (0x03 << blockIndex * 2)) >> blockIndex * 2]; if (blockY < 2) { colorInBlock.a = alphaPalette[alphaBlockIndex1 & 0x07]; } else { colorInBlock.a = alphaPalette[alphaBlockIndex2 & 0x07]; } texture2DColors[((row * width) + col) + ((blockY * width) + blockX)] = colorInBlock; blockIndex++; } alphaBlockIndex1 >>= 3; alphaBlockIndex2 >>= 3; } #endregion } } return(texture2DColors.ToArray()); }