mirror of https://github.com/SixLabors/ImageSharp
1 changed files with 117 additions and 0 deletions
@ -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 |
|||
{ |
|||
/// <summary>
|
|||
/// The header bytes identifying RIFF file.
|
|||
/// </summary>
|
|||
public static readonly uint RiffFourCc = 0x52_49_46_46; |
|||
|
|||
public static void WriteRiffFile(Stream stream, string formType, Action<Stream> func) => |
|||
WriteChunk(stream, RiffFourCc, s => |
|||
{ |
|||
s.Write(Encoding.ASCII.GetBytes(formType)); |
|||
func(s); |
|||
}); |
|||
|
|||
public static void WriteChunk(Stream stream, uint fourCc, Action<Stream> func) |
|||
{ |
|||
Span<byte> 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<byte> data) |
|||
{ |
|||
Span<byte> 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<TStruct>(Stream stream, uint fourCc, in TStruct chunk) |
|||
where TStruct : unmanaged |
|||
{ |
|||
fixed (TStruct* ptr = &chunk) |
|||
{ |
|||
WriteChunk(stream, fourCc, new Span<byte>(ptr, sizeof(TStruct))); |
|||
} |
|||
} |
|||
|
|||
public static long BeginWriteChunk(Stream stream, uint fourCc) |
|||
{ |
|||
Span<byte> 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<byte> 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; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue