mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 107 additions and 76 deletions
@ -0,0 +1,92 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Buffers.Binary; |
||||
|
using System.Text; |
||||
|
using static SixLabors.ImageSharp.Metadata.Profiles.Exif.EncodedString; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif |
||||
|
{ |
||||
|
internal static class ExifEncodedStringHelpers |
||||
|
{ |
||||
|
public const int CharacterCodeBytesLength = 8; |
||||
|
|
||||
|
private const ulong AsciiCode = 0x_41_53_43_49_49_00_00_00; |
||||
|
private const ulong JISCode = 0x_4A_49_53_00_00_00_00_00; |
||||
|
private const ulong UnicodeCode = 0x_55_4E_49_43_4F_44_45_00; |
||||
|
private const ulong UndefinedCode = 0x_00_00_00_00_00_00_00_00; |
||||
|
|
||||
|
private static ReadOnlySpan<byte> AsciiCodeBytes => new byte[] { 0x41, 0x53, 0x43, 0x49, 0x49, 0, 0, 0 }; |
||||
|
|
||||
|
private static ReadOnlySpan<byte> JISCodeBytes => new byte[] { 0x4A, 0x49, 0x53, 0, 0, 0, 0, 0 }; |
||||
|
|
||||
|
private static ReadOnlySpan<byte> UnicodeCodeBytes => new byte[] { 0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0 }; |
||||
|
|
||||
|
private static ReadOnlySpan<byte> UndefinedCodeBytes => new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; |
||||
|
|
||||
|
private static Encoding JIS0208Encoding => Encoding.GetEncoding(932); |
||||
|
|
||||
|
private static bool TryDetect(ReadOnlySpan<byte> buffer, out CharacterCode code) |
||||
|
{ |
||||
|
if (buffer.Length >= CharacterCodeBytesLength) |
||||
|
{ |
||||
|
ulong test = BinaryPrimitives.ReadUInt64LittleEndian(buffer); |
||||
|
switch (test) |
||||
|
{ |
||||
|
case AsciiCode: |
||||
|
code = CharacterCode.ASCII; |
||||
|
return true; |
||||
|
case JISCode: |
||||
|
code = CharacterCode.JIS; |
||||
|
return true; |
||||
|
case UnicodeCode: |
||||
|
code = CharacterCode.Unicode; |
||||
|
return true; |
||||
|
case UndefinedCode: |
||||
|
code = CharacterCode.Undefined; |
||||
|
return true; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
code = default; |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public static ReadOnlySpan<byte> GetCodeBytes(CharacterCode code) => code switch |
||||
|
{ |
||||
|
CharacterCode.ASCII => AsciiCodeBytes, |
||||
|
CharacterCode.JIS => JISCodeBytes, |
||||
|
CharacterCode.Unicode => UnicodeCodeBytes, |
||||
|
CharacterCode.Undefined => UndefinedCodeBytes, |
||||
|
_ => UndefinedCodeBytes |
||||
|
}; |
||||
|
|
||||
|
public static Encoding GetEncoding(CharacterCode code) => code switch |
||||
|
{ |
||||
|
CharacterCode.ASCII => Encoding.ASCII, |
||||
|
CharacterCode.JIS => JIS0208Encoding, |
||||
|
CharacterCode.Unicode => Encoding.Unicode, |
||||
|
CharacterCode.Undefined => Encoding.UTF8, |
||||
|
_ => Encoding.UTF8 |
||||
|
}; |
||||
|
|
||||
|
public static bool TryCreate(ReadOnlySpan<byte> buffer, out EncodedString encodedString) |
||||
|
{ |
||||
|
if (TryDetect(buffer, out CharacterCode code)) |
||||
|
{ |
||||
|
string text = GetEncoding(code).GetString(buffer.Slice(CharacterCodeBytesLength)); |
||||
|
encodedString = new EncodedString(code, text); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
encodedString = default; |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public static uint GetDataLength(EncodedString encodedString) => |
||||
|
(uint)GetEncoding(encodedString.Code).GetByteCount(encodedString.Text) + CharacterCodeBytesLength; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue