From 801b93aed4bf5c9addabf30307219f3a27c31156 Mon Sep 17 00:00:00 2001 From: Crsky Date: Sun, 1 Mar 2026 03:32:40 +0800 Subject: [PATCH] feat: Support Khronos texture format --- ArcFormats/ArcFormats.csproj | 13 +++++ ArcFormats/ImageKTX.cs | 110 +++++++++++++++++++++++++++++++++++ ArcFormats/packages.config | 4 ++ 3 files changed, 127 insertions(+) create mode 100644 ArcFormats/ImageKTX.cs diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index 52659b01..893348cf 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -52,9 +52,21 @@ MinimumRecommendedRules.ruleset + + ..\packages\BCnEncoder.Net.2.2.1\lib\netstandard2.0\BCnEncoder.dll + + + ..\packages\CommunityToolkit.HighPerformance.8.4.0\lib\netstandard2.0\CommunityToolkit.HighPerformance.dll + ..\packages\SharpZipLib.1.4.2\lib\netstandard2.0\ICSharpCode.SharpZipLib.dll + + ..\packages\Microsoft.Bcl.HashCode.6.0.0\lib\net462\Microsoft.Bcl.HashCode.dll + + + ..\packages\Microsoft.Bcl.Numerics.10.0.3\lib\net462\Microsoft.Bcl.Numerics.dll + ..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll @@ -179,6 +191,7 @@ + diff --git a/ArcFormats/ImageKTX.cs b/ArcFormats/ImageKTX.cs new file mode 100644 index 00000000..891cc6ac --- /dev/null +++ b/ArcFormats/ImageKTX.cs @@ -0,0 +1,110 @@ +//! \file ImagePIC.cs +//! \date 2017 Dec 04 +//! \brief Soft House Sprite modified bitmap image. +// +// Copyright (C) 2017 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using BCnEncoder.Decoder; +using BCnEncoder.Shared; +using BCnEncoder.Shared.ImageFiles; +using System; +using System.ComponentModel.Composition; +using System.IO; +using System.Reflection; +using System.Windows.Media; + +namespace GameRes.Formats +{ + internal class KtxMetaData : ImageMetaData + { + public KtxHeader Header; + } + + [Export(typeof(ImageFormat))] + public class KtxFormat : ImageFormat + { + public override string Tag { get { return "KTX"; } } + public override string Description { get { return "Khronos texture format"; } } + public override uint Signature { get { return 0x58544BAB; } } + public override bool CanWrite { get { return false; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + var signature = file.ReadInt32 (); + if (0x58544BAB != signature) + return null; + file.Position = 0xC; + var header = new KtxHeader + { + Endianness = file.ReadUInt32 (), + GlType = (GlType) file.ReadUInt32 (), + GlTypeSize = file.ReadUInt32 (), + GlFormat = (GlFormat) file.ReadUInt32 (), + GlInternalFormat = (GlInternalFormat) file.ReadUInt32 (), + GlBaseInternalFormat = (GlFormat) file.ReadUInt32 (), + PixelWidth = file.ReadUInt32 (), + PixelHeight = file.ReadUInt32 (), + PixelDepth = file.ReadUInt32 (), + NumberOfArrayElements = file.ReadUInt32 (), + NumberOfFaces = file.ReadUInt32 (), + NumberOfMipmapLevels = file.ReadUInt32 (), + BytesOfKeyValueData = file.ReadUInt32 (), + }; + var ktx = new KtxFile (header); + var decoder = new BcDecoder (); + if (!decoder.IsSupportedFormat (ktx)) + return null; + return new KtxMetaData + { + Width = header.PixelWidth, + Height = header.PixelHeight, + BPP = 32, + Header = header, + }; + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + var ktx = KtxFile.Load (file.AsStream); + var decoder = new BcDecoder (); + var buffer = decoder.Decode (ktx); + var pixels = new byte[buffer.Length*4]; + var src = 0; + var dst = 0; + while (src < buffer.Length) + { + pixels[dst ] = buffer[src].b; + pixels[dst+1] = buffer[src].g; + pixels[dst+2] = buffer[src].r; + pixels[dst+3] = buffer[src].a; + src += 1; + dst += 4; + } + return ImageData.Create (info, PixelFormats.Bgra32, null, pixels); + } + + public override void Write (Stream file, ImageData image) + { + throw new NotImplementedException ("KtxFormat.Write not implemented"); + } + } +} diff --git a/ArcFormats/packages.config b/ArcFormats/packages.config index c23913ab..b86e6902 100644 --- a/ArcFormats/packages.config +++ b/ArcFormats/packages.config @@ -1,5 +1,9 @@  + + + +