From 296da738008b06ea511b4e0123d059aa4e660a89 Mon Sep 17 00:00:00 2001 From: Poker Date: Fri, 3 Nov 2023 14:26:50 +0800 Subject: [PATCH 1/3] add riif helper --- src/ImageSharp/Common/Helpers/RiffHelper.cs | 117 ++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/ImageSharp/Common/Helpers/RiffHelper.cs diff --git a/src/ImageSharp/Common/Helpers/RiffHelper.cs b/src/ImageSharp/Common/Helpers/RiffHelper.cs new file mode 100644 index 0000000000..6354ebd663 --- /dev/null +++ b/src/ImageSharp/Common/Helpers/RiffHelper.cs @@ -0,0 +1,117 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Buffers.Binary; +using System.Text; + +namespace SixLabors.ImageSharp.Common.Helpers; + +internal class RiffHelper +{ + /// + /// The header bytes identifying RIFF file. + /// + public static readonly uint RiffFourCc = 0x52_49_46_46; + + public static void WriteRiffFile(Stream stream, string formType, Action func) => + WriteChunk(stream, RiffFourCc, s => + { + s.Write(Encoding.ASCII.GetBytes(formType)); + func(s); + }); + + public static void WriteChunk(Stream stream, uint fourCc, Action func) + { + Span buffer = stackalloc byte[4]; + + // write the fourCC + BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + stream.Write(buffer); + + long sizePosition = stream.Position; + stream.Position += 4; + + func(stream); + + long position = stream.Position; + stream.Position = sizePosition; + + uint dataSize = (uint)(position - sizePosition - 4); + + // padding + if (dataSize % 2 == 1) + { + stream.WriteByte(0); + position++; + } + + BinaryPrimitives.WriteUInt32LittleEndian(buffer, dataSize); + stream.Write(buffer); + + stream.Position = position; + } + + public static void WriteChunk(Stream stream, uint fourCc, ReadOnlySpan data) + { + Span buffer = stackalloc byte[4]; + + // write the fourCC + BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + stream.Write(buffer); + uint size = (uint)data.Length; + BinaryPrimitives.WriteUInt32LittleEndian(buffer, size); + stream.Write(buffer); + stream.Write(data); + + // padding + if (size % 2 == 1) + { + stream.WriteByte(0); + } + } + + public static unsafe void WriteChunk(Stream stream, uint fourCc, in TStruct chunk) + where TStruct : unmanaged + { + fixed (TStruct* ptr = &chunk) + { + WriteChunk(stream, fourCc, new Span(ptr, sizeof(TStruct))); + } + } + + public static long BeginWriteChunk(Stream stream, uint fourCc) + { + Span buffer = stackalloc byte[4]; + + // write the fourCC + BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + stream.Write(buffer); + + long sizePosition = stream.Position; + stream.Position += 4; + + return sizePosition; + } + + public static void EndWriteChunk(Stream stream, long sizePosition) + { + Span buffer = stackalloc byte[4]; + + long position = stream.Position; + stream.Position = sizePosition; + + uint dataSize = (uint)(position - sizePosition - 4); + + // padding + if (dataSize % 2 == 1) + { + stream.WriteByte(0); + position++; + } + + BinaryPrimitives.WriteUInt32LittleEndian(buffer, dataSize); + stream.Write(buffer); + + stream.Position = position; + } +} From 9dc0cda95e1c810f3bd56db1803fc0aa6cea4a09 Mon Sep 17 00:00:00 2001 From: Poker Date: Fri, 3 Nov 2023 15:06:57 +0800 Subject: [PATCH 2/3] add static --- src/ImageSharp/Common/Helpers/RiffHelper.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/RiffHelper.cs b/src/ImageSharp/Common/Helpers/RiffHelper.cs index 6354ebd663..0395d9a9c9 100644 --- a/src/ImageSharp/Common/Helpers/RiffHelper.cs +++ b/src/ImageSharp/Common/Helpers/RiffHelper.cs @@ -6,12 +6,12 @@ using System.Text; namespace SixLabors.ImageSharp.Common.Helpers; -internal class RiffHelper +internal static class RiffHelper { /// /// The header bytes identifying RIFF file. /// - public static readonly uint RiffFourCc = 0x52_49_46_46; + private const uint RiffFourCc = 0x52_49_46_46; public static void WriteRiffFile(Stream stream, string formType, Action func) => WriteChunk(stream, RiffFourCc, s => @@ -64,7 +64,7 @@ internal class RiffHelper stream.Write(data); // padding - if (size % 2 == 1) + if (size % 2 is 1) { stream.WriteByte(0); } @@ -103,7 +103,7 @@ internal class RiffHelper uint dataSize = (uint)(position - sizePosition - 4); // padding - if (dataSize % 2 == 1) + if (dataSize % 2 is 1) { stream.WriteByte(0); position++; @@ -114,4 +114,13 @@ internal class RiffHelper stream.Position = position; } + + public static long BeginWriteRiffFile(Stream stream, string formType) + { + long sizePosition = BeginWriteChunk(stream, RiffFourCc); + stream.Write(Encoding.ASCII.GetBytes(formType)); + return sizePosition; + } + + public static void EndWriteRiffFile(Stream stream, long sizePosition) => EndWriteChunk(stream, sizePosition); } From 4beafcf65586ff2631fefd2d6b1aedc1422ab4c8 Mon Sep 17 00:00:00 2001 From: Poker Date: Fri, 3 Nov 2023 17:16:44 +0800 Subject: [PATCH 3/3] fix FourCC bug --- src/ImageSharp/Common/Helpers/RiffHelper.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/RiffHelper.cs b/src/ImageSharp/Common/Helpers/RiffHelper.cs index 0395d9a9c9..8f06e5886f 100644 --- a/src/ImageSharp/Common/Helpers/RiffHelper.cs +++ b/src/ImageSharp/Common/Helpers/RiffHelper.cs @@ -25,7 +25,7 @@ internal static class RiffHelper Span buffer = stackalloc byte[4]; // write the fourCC - BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + BinaryPrimitives.WriteUInt32BigEndian(buffer, fourCc); stream.Write(buffer); long sizePosition = stream.Position; @@ -34,7 +34,6 @@ internal static class RiffHelper func(stream); long position = stream.Position; - stream.Position = sizePosition; uint dataSize = (uint)(position - sizePosition - 4); @@ -46,8 +45,8 @@ internal static class RiffHelper } BinaryPrimitives.WriteUInt32LittleEndian(buffer, dataSize); + stream.Position = sizePosition; stream.Write(buffer); - stream.Position = position; } @@ -56,7 +55,7 @@ internal static class RiffHelper Span buffer = stackalloc byte[4]; // write the fourCC - BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + BinaryPrimitives.WriteUInt32BigEndian(buffer, fourCc); stream.Write(buffer); uint size = (uint)data.Length; BinaryPrimitives.WriteUInt32LittleEndian(buffer, size); @@ -84,7 +83,7 @@ internal static class RiffHelper Span buffer = stackalloc byte[4]; // write the fourCC - BinaryPrimitives.WriteUInt32LittleEndian(buffer, fourCc); + BinaryPrimitives.WriteUInt32BigEndian(buffer, fourCc); stream.Write(buffer); long sizePosition = stream.Position; @@ -98,7 +97,6 @@ internal static class RiffHelper Span buffer = stackalloc byte[4]; long position = stream.Position; - stream.Position = sizePosition; uint dataSize = (uint)(position - sizePosition - 4); @@ -110,8 +108,8 @@ internal static class RiffHelper } BinaryPrimitives.WriteUInt32LittleEndian(buffer, dataSize); + stream.Position = sizePosition; stream.Write(buffer); - stream.Position = position; }