private void Write(FileInfo f) { var cr2w = new CR2WFile(); var mask = new Multilayer_Mask { CookingPlatform = Enums.ECookingPlatform.PLATFORM_PC }; cr2w.RootChunk = mask; var blob = new rendRenderMultilayerMaskBlobPC { Header = new rendRenderMultilayerMaskBlobHeader { Version = 3, AtlasWidth = _mlmask.AtlasWidth, AtlasHeight = _mlmask.AtlasHeight, NumLayers = (uint)_mlmask.Layers.Length, MaskWidth = _mlmask.WidthHigh, MaskHeight = _mlmask.HeightHigh, MaskWidthLow = _mlmask.WidthLow, MaskHeightLow = _mlmask.HeightLow, MaskTileSize = _mlmask.TileSize, Flags = 2 }, AtlasData = new SerializationDeferredDataBuffer(_mlmask.AtlasBuffer), TilesData = new SerializationDeferredDataBuffer(_mlmask.TilesBuffer) }; mask.RenderResourceBlob.RenderResourceBlobPC = blob; if (!Directory.Exists(f.Directory.FullName)) { Directory.CreateDirectory(f.Directory.FullName); } using var fs = new FileStream(f.FullName, FileMode.Create, FileAccess.Write); using var writer = new CR2WWriter(fs); writer.WriteFile(cr2w); }
void Write(FileInfo f) { CR2WFile cr2w = new CR2WFile(); { var blob = new Multilayer_Mask(cr2w, null, "Multilayer_Mask") { IsSerialized = true }; blob.CookingPlatform = new CEnum <Enums.ECookingPlatform>(cr2w, blob, "cookingPlatform") { IsSerialized = true, Value = Enums.ECookingPlatform.PLATFORM_PC }; blob.CookingPlatform.EnumValueList.Add("PLATFORM_PC"); blob.RenderResourceBlob.RenderResourceBlobPC = new CHandle <IRenderResourceBlob>(cr2w, blob.RenderResourceBlob, "renderResourceBlobPC") { IsSerialized = true }; cr2w.CreateChunk(blob, 0); } { var blob = new rendRenderMultilayerMaskBlobPC(cr2w, null, "rendRenderMultilayerMaskBlobPC") { IsSerialized = true }; blob.Header = new rendRenderMultilayerMaskBlobHeader(cr2w, blob, "header") { IsSerialized = true }; blob.Header.Version = new CUInt32(cr2w, blob.Header, "version") { IsSerialized = true, Value = 3 }; blob.Header.AtlasWidth = new CUInt32(cr2w, blob.Header, "atlasWidth") { IsSerialized = true, Value = mlmask._atlasWidth }; blob.Header.AtlasHeight = new CUInt32(cr2w, blob.Header, "atlasHeight") { IsSerialized = true, Value = mlmask._atlasHeight }; blob.Header.NumLayers = new CUInt32(cr2w, blob.Header, "numLayers") { IsSerialized = true, Value = (uint)mlmask.layers.Length }; blob.Header.MaskWidth = new CUInt32(cr2w, blob.Header, "maskWidth") { IsSerialized = true, Value = mlmask._widthHigh }; blob.Header.MaskHeight = new CUInt32(cr2w, blob.Header, "maskHeight") { IsSerialized = true, Value = mlmask._heightHigh }; blob.Header.MaskWidthLow = new CUInt32(cr2w, blob.Header, "maskWidthLow") { IsSerialized = true, Value = mlmask._widthLow }; blob.Header.MaskHeightLow = new CUInt32(cr2w, blob.Header, "maskHeightLow") { IsSerialized = true, Value = mlmask._heightLow }; blob.Header.MaskTileSize = new CUInt32(cr2w, blob.Header, "maskTileSize") { IsSerialized = true, Value = mlmask._tileSize }; blob.Header.Flags = new CUInt32(cr2w, blob.Header, "flags") { IsSerialized = true, Value = 2 }; blob.AtlasData = new serializationDeferredDataBuffer(cr2w, blob, "atlasData") { IsSerialized = true }; blob.AtlasData.Buffer = new CUInt16(cr2w, blob.AtlasData, "Buffer") { IsSerialized = true, Value = 1 }; blob.TilesData = new serializationDeferredDataBuffer(cr2w, blob, "tilesData") { IsSerialized = true }; blob.TilesData.Buffer = new CUInt16(cr2w, blob.TilesData, "Buffer") { IsSerialized = true, Value = 2 }; cr2w.CreateChunk(blob, 1); } (cr2w.Chunks[0].Data as Multilayer_Mask).RenderResourceBlob.RenderResourceBlobPC.SetReference(cr2w.Chunks[1]); //test write var ms = new MemoryStream(); var bw = new BinaryWriter(ms); using (var compressed = new MemoryStream()) { using var buff = new BinaryWriter(compressed); var(zsize, crc) = buff.CompressAndWrite(mlmask._AtlasBuffer); cr2w.Buffers.Add(new CR2WBufferWrapper(new CR2WBuffer() { flags = 0, index = 0, offset = 0, diskSize = zsize, memSize = (UInt32)mlmask._AtlasBuffer.Length, crc32 = crc })); cr2w.Buffers[0].ReadData(new BinaryReader(compressed)); // to get offset cr2w.Write(bw); cr2w.Buffers[0].Offset = (uint)ms.Length; } using (var compressed = new MemoryStream()) { using var buff = new BinaryWriter(compressed); var(zsize, crc) = buff.CompressAndWrite(mlmask._tilesBuffer); cr2w.Buffers.Add(new CR2WBufferWrapper(new CR2WBuffer() { flags = 0, index = 1, offset = 0, diskSize = zsize, memSize = (UInt32)mlmask._tilesBuffer.Length, crc32 = crc })); cr2w.Buffers[1].ReadData(new BinaryReader(compressed)); cr2w.Buffers[1].Offset = cr2w.Buffers[0].Offset + cr2w.Buffers[0].DiskSize; } cr2w.Write(bw); if (!Directory.Exists(f.Directory.FullName)) { Directory.CreateDirectory(f.Directory.FullName); } File.WriteAllBytes(f.FullName, ms.ToArray()); }
public static bool ConvertMultilayerMaskToDdsStreams(Multilayer_Mask mask, out List <Stream> streams) { streams = new List <Stream>(); if (mask.RenderResourceBlob.RenderResourceBlobPC.GetValue() is not rendRenderMultilayerMaskBlobPC blob) { return(false); } uint atlasWidth = blob.Header.AtlasWidth; uint atlasHeight = blob.Header.AtlasHeight; uint maskWidth = blob.Header.MaskWidth; uint maskHeight = blob.Header.MaskHeight; uint maskWidthLow = blob.Header.MaskWidthLow; uint maskHeightLow = blob.Header.MaskHeightLow; uint maskTileSize = blob.Header.MaskTileSize; uint maskCount = blob.Header.NumLayers; var atlasRaw = new byte[atlasWidth * atlasHeight]; //Decode compressed data into single channel uncompressed //Mlmask always BC4? if (!BlockCompression.DecodeBC(blob.AtlasData.Buffer.GetBytes(), ref atlasRaw, atlasWidth, atlasHeight, BlockCompression.BlockCompressionType.BC4)) { return(false); } //atlasRaw = blob.AtlasData.Buffer.GetBytes(); //Read tilesdata buffer into appropriate variable type var tileBuffer = blob.TilesData.Buffer; var tiles = new uint[tileBuffer.MemSize / 4]; using (var ms = new MemoryStream(tileBuffer.GetBytes())) using (var br = new BinaryReader(ms)) { ms.Seek(0, SeekOrigin.Begin); for (var i = 0; i < tiles.Length; i++) { tiles[i] = br.ReadUInt32(); } } var maskData = new byte[maskWidth * maskHeight]; for (var i = 0; i < maskCount; i++) { //Clear instead of allocate new is faster? //Mandatory cause decode does not always write to every pixel Array.Clear(maskData, 0, maskData.Length); try { Decode(ref maskData, maskWidth, maskHeight, maskWidthLow, maskHeightLow, atlasRaw, atlasWidth, atlasHeight, tiles, maskTileSize, i); } catch { throw; } if (WolvenTesting.IsTesting) { continue; } var ms = new MemoryStream(); DDSUtils.GenerateAndWriteHeader(ms, new DDSMetadata(maskWidth, maskHeight, 1, 1, 0, 0, 0, DXGI_FORMAT.DXGI_FORMAT_R8_UNORM, TEX_DIMENSION.TEX_DIMENSION_TEXTURE2D, 8, true)); ms.Write(maskData); ms.Seek(0, SeekOrigin.Begin); //var stream = new MemoryStream(DDSUtils.ConvertToDdsMemory(ms, EUncookExtension.tga, DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM, false, false)); ms = new MemoryStream( Texconv.ConvertToDds( new MemoryStream(Texconv.ConvertFromDds(ms, EUncookExtension.tga)), EUncookExtension.tga, DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM)); streams.Add(ms); } return(true); }