public static byte[] Headerize(TPF.Texture texture) { if (Encoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ") { return(texture.Bytes); } DDS dds = new DDS(); PIXELFORMAT ddspf = dds.ddspf; byte format = texture.Format; if (format != 16 && format != 26) { DDSD dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT; if (format == 0 || format == 1 || format == 3 || format == 5) { dwFlags |= DDSD.LINEARSIZE; } else if (format == 9 || format == 10) { dwFlags |= DDSD.PITCH; } dds.dwFlags = dwFlags; dds.dwHeight = texture.Header.Height; dds.dwWidth = texture.Header.Width; if (format == 9 || format == 10) { dds.dwPitchOrLinearSize = (texture.Header.Width * 32 + 7) / 8; } //else if (format == 0 || format == 1) // pitch = Math.Max(1, (texture.Header.Width + 3) / 4) * (8 * 8 * 8); //else if (format == 5) // pitch = Math.Max(1, (texture.Header.Width + 3) / 4) * (16 * 16 * 8); dds.dwDepth = 1; dds.dwMipMapCount = texture.Mipmaps; DDPF ddspfdwFlags = 0; if (format == 0 || format == 1 || format == 3 || format == 5) { ddspfdwFlags |= DDPF.FOURCC; } else if (format == 9) { ddspfdwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } else if (format == 10) { ddspfdwFlags |= DDPF.RGB; } ddspf.dwFlags = ddspfdwFlags; if (format == 0 || format == 1) { ddspf.SetFourCCAsString("DXT1"); } else if (format == 3) { ddspf.SetFourCCAsString("DXT3"); } else if (format == 5) { ddspf.SetFourCCAsString("DXT5"); } else { ddspf.dwFourCC = 0; } if (format == 9 || format == 10) { ddspf.dwRGBBitCount = 32; } if (format == 9) { ddspf.dwRBitMask = 0x00FF0000; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x000000FF; ddspf.dwABitMask = 0xFF000000; } else if (format == 10) { ddspf.dwRBitMask = 0x000000FF; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x00FF0000; ddspf.dwABitMask = 0x00000000; } DDSCAPS dwCaps = DDSCAPS.TEXTURE; if (texture.Type == TPF.TexType.Cubemap) { dwCaps |= DDSCAPS.COMPLEX; } if (texture.Mipmaps > 1) { dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP; } dds.dwCaps = dwCaps; if (texture.Type == TPF.TexType.Cubemap) { dds.dwCaps2 = CUBEMAP_ALLFACES; } else if (texture.Type == TPF.TexType.Volume) { dds.dwCaps2 = DDSCAPS2.VOLUME; } } else { //int a = 0; } return(dds.Write(texture.Bytes)); }
public static byte[] Headerize(TPF.Texture texture) { if (SFEncoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ") { return(texture.Bytes); } var dds = new DDS(); byte format = texture.Format; short width = texture.Header.Width; short height = texture.Header.Height; int mipCount = texture.Mipmaps; TPF.TexType type = texture.Type; dds.dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT; if (CompressedBPB.ContainsKey(format)) { dds.dwFlags |= DDSD.PITCH; } else if (UncompressedBPP.ContainsKey(format)) { dds.dwFlags |= DDSD.LINEARSIZE; } dds.dwHeight = height; dds.dwWidth = width; if (CompressedBPB.ContainsKey(format)) { dds.dwPitchOrLinearSize = Math.Max(1, (width + 3) / 4) * CompressedBPB[format]; } else if (UncompressedBPP.ContainsKey(format)) { dds.dwPitchOrLinearSize = (width * UncompressedBPP[format] + 7) / 8; } if (mipCount == 0) { mipCount = DetermineMipCount(width, height); } dds.dwMipMapCount = mipCount; dds.dwCaps = DDSCAPS.TEXTURE; if (type == TPF.TexType.Cubemap) { dds.dwCaps |= DDSCAPS.COMPLEX; } if (mipCount > 1) { dds.dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP; } if (type == TPF.TexType.Cubemap) { dds.dwCaps2 = CUBEMAP_ALLFACES; } else if (type == TPF.TexType.Volume) { dds.dwCaps2 = DDSCAPS2.VOLUME; } PIXELFORMAT ddspf = dds.ddspf; if (FourCC.ContainsKey(format) || DX10Formats.Contains(format)) { ddspf.dwFlags = DDPF.FOURCC; } if (format == 6) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } else if (format == 9) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } else if (format == 10) { ddspf.dwFlags |= DDPF.RGB; } else if (format == 16) { ddspf.dwFlags |= DDPF.ALPHA; } else if (format == 105) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } if (FourCC.ContainsKey(format)) { ddspf.dwFourCC = FourCC[format]; } else if (DX10Formats.Contains(format)) { ddspf.dwFourCC = "DX10"; } if (format == 6) { ddspf.dwRGBBitCount = 16; ddspf.dwRBitMask = 0b01111100_00000000; ddspf.dwGBitMask = 0b00000011_11100000; ddspf.dwBBitMask = 0b00000000_00011111; ddspf.dwABitMask = 0b10000000_00000000; } else if (format == 9) { ddspf.dwRGBBitCount = 32; ddspf.dwRBitMask = 0x00FF0000; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x000000FF; ddspf.dwABitMask = 0xFF000000; } else if (format == 10) { ddspf.dwRGBBitCount = 24; ddspf.dwRBitMask = 0x00FF0000; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x000000FF; } else if (format == 16) { ddspf.dwRGBBitCount = 8; ddspf.dwABitMask = 0x000000FF; } else if (format == 105) { ddspf.dwRGBBitCount = 32; ddspf.dwRBitMask = 0x000000FF; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x00FF0000; ddspf.dwABitMask = 0xFF000000; } if (DX10Formats.Contains(format)) { dds.header10 = new HEADER_DXT10(); dds.header10.dxgiFormat = (DXGI_FORMAT)texture.Header.DXGIFormat; if (type == TPF.TexType.Cubemap) { dds.header10.miscFlag = RESOURCE_MISC.TEXTURECUBE; } } byte[] bytes = texture.Bytes; int imageCount = type == TPF.TexType.Cubemap ? 6 : 1; List <Image> images = null; if (CompressedBPB.ContainsKey(format)) { images = Image.ReadCompressed(bytes, width, height, imageCount, mipCount, 0x80, CompressedBPB[format]); } else if (UncompressedBPP.ContainsKey(format)) { images = Image.ReadUncompressed(bytes, width, height, imageCount, mipCount, 0x80, UncompressedBPP[format]); } if (format == 10) { int texelSize = -1; int texelWidth = -1; if (format == 10) { texelSize = 4; texelWidth = width; } foreach (Image image in images) { for (int i = 0; i < image.MipLevels.Count; i++) { byte[] swizzled = image.MipLevels[i]; byte[] unswizzled = DeswizzlePS3(swizzled, texelSize, texelWidth / (int)Math.Pow(2, i)); if (format == 10) { byte[] trimmed = new byte[unswizzled.Length / 4 * 3]; for (int j = 0; j < unswizzled.Length / 4; j++) { Array.Reverse(unswizzled, j * 4, 4); Array.Copy(unswizzled, j * 4, trimmed, j * 3, 3); } unswizzled = trimmed; } image.MipLevels[i] = unswizzled; } } } if (images != null) { bytes = Image.Write(images); } return(dds.Write(bytes)); }
internal void WriteHeader(BinaryWriterEx bw, int index, TPFPlatform platform, byte flag2) { if (platform == TPFPlatform.PC) { DDS dds = new DDS(Bytes); if (dds.dwCaps2.HasFlag(DDS.DDSCAPS2.CUBEMAP)) { Type = TexType.Cubemap; } else if (dds.dwCaps2.HasFlag(DDS.DDSCAPS2.VOLUME)) { Type = TexType.Volume; } else { Type = TexType.Texture; } Mipmaps = (byte)dds.dwMipMapCount; } bw.ReserveUInt32($"FileData{index}"); bw.ReserveInt32($"FileSize{index}"); bw.WriteByte(Format); bw.WriteByte((byte)Type); bw.WriteByte(Mipmaps); bw.WriteByte(Flags1); if (platform != TPFPlatform.PC) { bw.WriteInt16(Header.Width); bw.WriteInt16(Header.Height); if (platform == TPFPlatform.Xbox360) { bw.WriteInt32(0); } else if (platform == TPFPlatform.PS3) { bw.WriteInt32(Header.Unk1); if (flag2 != 0) { bw.WriteInt32(Header.Unk2); } } else if (platform == TPFPlatform.PS4 || platform == TPFPlatform.Xbone) { bw.WriteInt32(Header.TextureCount); bw.WriteInt32(Header.Unk2); } } bw.ReserveUInt32($"FileName{index}"); bw.WriteInt32(FloatStruct == null ? 0 : 1); if (platform == TPFPlatform.PS4 || platform == TPFPlatform.Xbone) { bw.WriteInt32(Header.DXGIFormat); } if (FloatStruct != null) { FloatStruct.Write(bw); } }
public static byte[] Headerize(TPF.Texture texture) { if (SFEncoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ") { return(texture.Bytes); } var dds = new DDS(); byte format = texture.Format; short width = texture.Header.Width; short height = texture.Header.Height; int mipCount = texture.Mipmaps; TPF.TexType type = texture.Type; dds.dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT; if (CompressedBPB.ContainsKey(format)) { dds.dwFlags |= DDSD.LINEARSIZE; } else if (UncompressedBPP.ContainsKey(format)) { dds.dwFlags |= DDSD.PITCH; } dds.dwHeight = height; dds.dwWidth = width; if (CompressedBPB.ContainsKey(format)) { dds.dwPitchOrLinearSize = Math.Max(1, (width + 3) / 4) * CompressedBPB[format]; } else if (UncompressedBPP.ContainsKey(format)) { dds.dwPitchOrLinearSize = (width * UncompressedBPP[format] + 7) / 8; } // This line serves only to remind me that I didn't forget about dwDepth, I left it 0 on purpose. dds.dwDepth = 0; if (mipCount == 0) { mipCount = DetermineMipCount(width, height); } dds.dwMipMapCount = mipCount; dds.dwCaps = DDSCAPS.TEXTURE; if (type == TPF.TexType.Cubemap) { dds.dwCaps |= DDSCAPS.COMPLEX; } if (mipCount > 1) { dds.dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP; } if (type == TPF.TexType.Cubemap) { dds.dwCaps2 = CUBEMAP_ALLFACES; } else if (type == TPF.TexType.Volume) { dds.dwCaps2 = DDSCAPS2.VOLUME; } PIXELFORMAT ddspf = dds.ddspf; if (FourCC.ContainsKey(format) || DX10Formats.Contains(format)) { ddspf.dwFlags = DDPF.FOURCC; } if (format == 6) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } else if (format == 9) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } else if (format == 10) { ddspf.dwFlags |= DDPF.RGB; } else if (format == 16) { ddspf.dwFlags |= DDPF.ALPHA; } else if (format == 105) { ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB; } if (FourCC.ContainsKey(format)) { ddspf.dwFourCC = FourCC[format]; } else if (DX10Formats.Contains(format)) { ddspf.dwFourCC = "DX10"; } if (format == 6) { ddspf.dwRGBBitCount = 16; ddspf.dwRBitMask = 0b01111100_00000000; ddspf.dwGBitMask = 0b00000011_11100000; ddspf.dwBBitMask = 0b00000000_00011111; ddspf.dwABitMask = 0b10000000_00000000; } else if (format == 9) { ddspf.dwRGBBitCount = 32; ddspf.dwRBitMask = 0x00FF0000; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x000000FF; ddspf.dwABitMask = 0xFF000000; } else if (format == 10) { ddspf.dwRGBBitCount = 24; ddspf.dwRBitMask = 0x00FF0000; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x000000FF; } else if (format == 16) { ddspf.dwRGBBitCount = 8; ddspf.dwABitMask = 0x000000FF; } else if (format == 105) { ddspf.dwRGBBitCount = 32; ddspf.dwRBitMask = 0x000000FF; ddspf.dwGBitMask = 0x0000FF00; ddspf.dwBBitMask = 0x00FF0000; ddspf.dwABitMask = 0xFF000000; } if (DX10Formats.Contains(format)) { dds.header10 = new HEADER_DXT10(); dds.header10.dxgiFormat = (DXGI_FORMAT)texture.Header.DXGIFormat; if (type == TPF.TexType.Cubemap) { dds.header10.miscFlag = RESOURCE_MISC.TEXTURECUBE; } } byte[] bytes = RebuildPixelData(texture.Bytes, format, width, height, mipCount, type); return(dds.Write(bytes)); }