private static int OodleTask(string path, string outpath, bool decompress, bool compress) { if (string.IsNullOrEmpty(path)) { return(0); } if (string.IsNullOrEmpty(outpath)) { outpath = Path.ChangeExtension(path, ".kark"); } if (decompress) { var file = File.ReadAllBytes(path); using var ms = new MemoryStream(file); using var br = new BinaryReader(ms); var oodleCompression = br.ReadBytes(4); if (!(oodleCompression.SequenceEqual(new byte[] { 0x4b, 0x41, 0x52, 0x4b }))) { throw new NotImplementedException(); } var size = br.ReadUInt32(); var buffer = br.ReadBytes(file.Length - 8); byte[] unpacked = new byte[size]; long unpackedSize = OodleHelper.Decompress(buffer, unpacked); using var msout = new MemoryStream(); using var bw = new BinaryWriter(msout); bw.Write(unpacked); File.WriteAllBytes($"{outpath}", msout.ToArray()); } if (compress) { var inbuffer = File.ReadAllBytes(path); IEnumerable <byte> outBuffer = new List <byte>(); var r = OodleHelper.Compress( inbuffer, inbuffer.Length, ref outBuffer, OodleNative.OodleLZ_Compressor.Kraken, OodleNative.OodleLZ_Compression.Normal, true); File.WriteAllBytes(outpath, outBuffer.ToArray()); } return(1); }
public void Read(BinaryReader br) { var magic = br.ReadUInt32(); if (magic != s_magic) { throw new InvalidParsingException("not a valid Archive"); } var version = br.ReadUInt32(); var size = br.ReadInt32(); var zsize = br.ReadInt32(); var count = br.ReadInt32(); var inbuffer = br.ReadBytes(zsize); if (size > zsize) { // buffer is compressed var outBuffer = new byte[size]; var r = OodleHelper.Decompress(inbuffer, outBuffer); using var ms = new MemoryStream(outBuffer); using var tempbr = new BinaryReader(ms); for (var i = 0; i < count; i++) { FileInfos.Add(tempbr.ReadCR2WString()); } } else if (size < zsize) { // error // extract as .bin file } else { // no compression using var ms = new MemoryStream(inbuffer); using var tempbr = new BinaryReader(ms); for (var i = 0; i < count; i++) { FileInfos.Add(tempbr.ReadCR2WString()); } } }
public static int OodleTask(string path, string outpath, bool decompress) { if (string.IsNullOrEmpty(path)) { return(0); } if (string.IsNullOrEmpty(outpath)) { outpath = path; } if (decompress) { var file = File.ReadAllBytes(path); using var ms = new MemoryStream(file); using var br = new BinaryReader(ms); var oodleCompression = br.ReadBytes(4); if (!(oodleCompression.SequenceEqual(new byte[] { 0x4b, 0x41, 0x52, 0x4b }))) { throw new NotImplementedException(); } var size = br.ReadUInt32(); var buffer = br.ReadBytes(file.Length - 8); byte[] unpacked = new byte[size]; long unpackedSize = OodleHelper.Decompress(buffer, unpacked); using var msout = new MemoryStream(); using var bw = new BinaryWriter(msout); bw.Write(unpacked); File.WriteAllBytes($"{outpath}.kark", msout.ToArray()); } return(1); }
public bool ExportAnim(Stream animStream, List <Archive> archives, FileInfo outfile, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.TryReadRED4File(animStream); if (!cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().Any()) { return(false); } var blob = cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().First(); List <MemoryStream> animDataBuffers = new List <MemoryStream>(); foreach (var chk in blob.AnimationDataChunks) { UInt16 bufferIdx = chk.Buffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); var ms = new MemoryStream(); animStream.DecompressAndCopySegment(ms, b.DiskSize, b.MemSize); animDataBuffers.Add(ms); } var Rig = new RawArmature(); var hash = FNV1A64HashAlgorithm.HashString(blob.Rig.DepotPath); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); Rig = RIG.ProcessRig(_wolvenkitFileService.TryReadRED4File(ms)); break; } } if (Rig is null) { return(false); } if (Rig.BoneCount < 1) { return(false); } var model = ModelRoot.CreateModel(); var skin = model.CreateSkin(); skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray()); for (int i = 0; i < blob.Animations.Count; i++) { var setEntry = (blob.Animations[i].GetReference().Data as animAnimSetEntry); var animAnimDes = (setEntry.Animation.GetReference().Data as animAnimation); if (animAnimDes.AnimationType.Value != Enums.animAnimationType.Normal) { continue; } switch (animAnimDes.AnimBuffer.GetReference().REDType) { case "animAnimationBufferSimd": { var animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferSimd); var defferedBuffer = new MemoryStream(); if (animBuff.InplaceCompressedBuffer.IsSerialized) { var bufferIdx = animBuff.InplaceCompressedBuffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize); var br = new BinaryReader(defferedBuffer); br.BaseStream.Seek(0, SeekOrigin.Begin); if (br.ReadUInt32() == OodleHelper.KARK) { uint size = br.ReadUInt32(); var input = br.ReadBytes((int)(br.BaseStream.Length - 8)); var output = new Byte[size]; OodleHelper.Decompress(input, output); defferedBuffer = new MemoryStream(output); } } else { var bufferIdx = animBuff.DefferedBuffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize); } defferedBuffer.Seek(0, SeekOrigin.Begin); SIMD.AddAnimationSIMD(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer, animAnimDes); } break; case "animAnimationBufferCompressed": { var animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferCompressed); var defferedBuffer = new MemoryStream(); if (animBuff.InplaceCompressedBuffer.IsSerialized) { var bufferIdx = animBuff.InplaceCompressedBuffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize); var br = new BinaryReader(defferedBuffer); br.BaseStream.Seek(0, SeekOrigin.Begin); if (br.ReadUInt32() == OodleHelper.KARK) { uint size = br.ReadUInt32(); var input = br.ReadBytes((int)(br.BaseStream.Length - 8)); var output = new Byte[size]; OodleHelper.Decompress(input, output); defferedBuffer = new MemoryStream(output); } } else if (animBuff.DataAddress.IsSerialized) { var dataAddr = animBuff.DataAddress; Byte[] bytes = new Byte[dataAddr.ZeInBytes.Value]; animDataBuffers[(int)dataAddr.UnkIndex.Value].Seek(dataAddr.FsetInBytes.Value, SeekOrigin.Begin); animDataBuffers[(int)dataAddr.UnkIndex.Value].Read(bytes, 0, (int)dataAddr.ZeInBytes.Value); defferedBuffer = new MemoryStream(bytes); } else if (animBuff.DefferedBuffer.IsSerialized) { var bufferIdx = animBuff.DefferedBuffer.Buffer.Value; var b = cr2w.Buffers[bufferIdx - 1]; animStream.Seek(b.Offset, SeekOrigin.Begin); animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize); } defferedBuffer.Seek(0, SeekOrigin.Begin); SPLINE.AddAnimationSpline(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer, animAnimDes); } break; } } if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } return(true); }