public static byte[] DecodeToDDS(FieldTexturePS3 texture) { var surfaceFormat = ImageEngineFormat.DDS_DXT1; if (texture.Flags.HasFlag(FieldTextureFlags.DXT3)) { surfaceFormat = ImageEngineFormat.DDS_DXT3; } else if (texture.Flags.HasFlag(FieldTextureFlags.DXT5)) { surfaceFormat = ImageEngineFormat.DDS_DXT5; } var ddsBytes = new byte[0x80 + texture.DataLength]; // create & write header var ddsHeader = new DDS_Header(texture.MipMapCount, texture.Height, texture.Width, surfaceFormat); ddsHeader.WriteToArray(ddsBytes, 0); // write pixel data Array.Copy(texture.Data, 0, ddsBytes, 0x80, texture.DataLength); return(ddsBytes); }
public static byte[] DecodeToDDS(GNFTexture texture) { var surfaceFormat = ImageEngineFormat.DDS_DXT1; if (texture.PixelFormat == 0x50) { surfaceFormat = ImageEngineFormat.DDS_DXT3; } var ddsBytes = new byte[0x80 + texture.Data.Length]; // create & write header var ddsHeader = new DDS_Header(1, texture.Height, texture.Width, surfaceFormat); ddsHeader.WriteToArray(ddsBytes, 0); // write pixel data Array.Copy(texture.Data, 0, ddsBytes, 0x80, texture.Data.Length); return(ddsBytes); }
internal static byte[] Save(List <MipMap> mipMaps, ImageFormats.ImageEngineFormatDetails destFormatDetails, AlphaSettings alphaSetting) { // Set compressor for Block Compressed textures Action <byte[], int, int, byte[], int, AlphaSettings, ImageFormats.ImageEngineFormatDetails> compressor = destFormatDetails.BlockEncoder; bool needCheckSize = destFormatDetails.IsBlockCompressed; int height = mipMaps[0].Height; int width = mipMaps[0].Width; if (needCheckSize && !CheckSize_DXT(width, height)) { throw new InvalidOperationException($"DXT compression formats require dimensions to be multiples of 4. Got: {width}x{height}."); } // Create header and write to destination DDS_Header header = new DDS_Header(mipMaps.Count, height, width, destFormatDetails.Format, destFormatDetails.DX10Format); int headerLength = destFormatDetails.HeaderSize; int fullSize = GetCompressedSizeOfImage(mipMaps.Count, destFormatDetails, width, height); /*if (destFormatDetails.ComponentSize != 1) * fullSize += (fullSize - headerLength) * destFormatDetails.ComponentSize;*/// Size adjustment for destination to allow for different component sizes. byte[] destination = new byte[fullSize]; header.WriteToArray(destination, 0); int blockSize = destFormatDetails.BlockSize; if (destFormatDetails.IsBlockCompressed) { int mipOffset = headerLength; foreach (MipMap mipmap in mipMaps) { if (ImageEngine.IsCancellationRequested) { break; } var temp = WriteCompressedMipMap(destination, mipOffset, mipmap, blockSize, compressor, alphaSetting); if (temp != -1) // When dimensions too low. { mipOffset = temp; } } } else { // UNCOMPRESSED var action = new Action <int>(mipIndex => { if (alphaSetting == AlphaSettings.RemoveAlphaChannel) { // Remove alpha by setting AMask = 0 var ddspf = header.ddspf; ddspf.dwABitMask = 0; header.ddspf = ddspf; } // Get MipOffset int offset = GetMipOffset(mipIndex, destFormatDetails, width, height); WriteUncompressedMipMap(destination, offset, mipMaps[mipIndex], destFormatDetails, header.ddspf); }); if (ImageEngine.EnableThreading) { Parallel.For(0, mipMaps.Count, new ParallelOptions { MaxDegreeOfParallelism = ImageEngine.NumThreads }, (mip, loopState) => { if (ImageEngine.IsCancellationRequested) { loopState.Stop(); } action(mip); }); } else { for (int i = 0; i < mipMaps.Count; i++) { if (ImageEngine.IsCancellationRequested) { break; } action(i); } } } return(ImageEngine.IsCancellationRequested ? null : destination); }
public static byte[] DecodeToDDS(GNFTexture texture) { var imageFormat = ImageEngineFormat.DDS_DXT5; var dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; switch (texture.SurfaceFormat) { case GNF.SurfaceFormat.BC1: imageFormat = ImageEngineFormat.DDS_DXT1; break; case GNF.SurfaceFormat.BC2: imageFormat = ImageEngineFormat.DDS_DXT2; break; case GNF.SurfaceFormat.BC3: imageFormat = ImageEngineFormat.DDS_DXT5; break; case GNF.SurfaceFormat.BC4: imageFormat = ImageEngineFormat.DDS_ATI1; break; case GNF.SurfaceFormat.BC5: imageFormat = ImageEngineFormat.DDS_ATI2_3Dc; break; case GNF.SurfaceFormat.BC6: imageFormat = ImageEngineFormat.DDS_DX10; dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16; break; case GNF.SurfaceFormat.BC7: imageFormat = ImageEngineFormat.DDS_DX10; switch (texture.ChannelType) { case ChannelType.Srgb: dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB; break; default: dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; break; } break; } var ddsHeaderSize = 0x80; if (dx10ImageFormat != DDS_Header.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN) { ddsHeaderSize += 20; } var ddsBytes = new byte[ddsHeaderSize + texture.Data.Length]; // create & write header var ddsHeader = new DDS_Header(1, texture.Height, texture.Width, imageFormat, dx10ImageFormat); ddsHeader.WriteToArray(ddsBytes, 0); // unswizzle var data = Swizzler.UnSwizzle(texture.Data, texture.Width, texture.Height, imageFormat == ImageEngineFormat.DDS_DXT1 ? 8 : 16, SwizzleType.PS4); // write pixel data Array.Copy(data, 0, ddsBytes, ddsHeaderSize, texture.Data.Length); return(ddsBytes); }