156 lines
4.6 KiB
C#
156 lines
4.6 KiB
C#
using System;
|
|
using System.Buffers;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using Quik.Media;
|
|
|
|
// WebRequest is obsolete but runs on .NET framework.
|
|
#pragma warning disable SYSLIB0014
|
|
|
|
namespace Quik.Media.Stb
|
|
{
|
|
public class StbMediaLoader : MediaLoader<string>, MediaLoader<Uri>, MediaLoader<FileInfo>, MediaLoader<FontInfo>
|
|
{
|
|
public bool AllowRemoteTransfers { get; set; } = false;
|
|
private readonly ArrayPool<byte> ByteArrays = ArrayPool<byte>.Create();
|
|
|
|
public IDisposable GetMedia(object key, MediaHint hint)
|
|
{
|
|
Type t = key.GetType();
|
|
/**/ if (t == typeof(string))
|
|
{
|
|
return GetMedia((string)key, hint);
|
|
}
|
|
else if (t == typeof(Uri))
|
|
{
|
|
return GetMedia((Uri)key, hint);
|
|
}
|
|
else if (t == typeof(FileInfo))
|
|
{
|
|
return GetMedia((FileInfo)key, hint);
|
|
}
|
|
else if (t == typeof(FontInfo))
|
|
{
|
|
return GetMedia((FontInfo)key, hint);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public IDisposable GetMedia(Uri uri, MediaHint hint)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public IDisposable GetMedia(string str, MediaHint hint)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public IDisposable GetMedia(FileInfo file, MediaHint hint)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public IDisposable GetMedia(FontInfo key, MediaHint hint)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public Stream OpenResource(FileInfo file)
|
|
{
|
|
if (file.Exists)
|
|
{
|
|
return file.Open(FileMode.Open);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public Stream OpenResource(Uri uri)
|
|
{
|
|
switch (uri.Scheme)
|
|
{
|
|
case "http":
|
|
case "https":
|
|
if (!AllowRemoteTransfers) return null;
|
|
|
|
try
|
|
{
|
|
WebRequest request = HttpWebRequest.Create(uri);
|
|
WebResponse response = request.GetResponse();
|
|
MemoryStream stream = new MemoryStream();
|
|
|
|
response.GetResponseStream().CopyTo(stream);
|
|
response.Close();
|
|
|
|
stream.Position = 0;
|
|
return stream;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
case "file":
|
|
return OpenResource(new FileInfo(uri.AbsolutePath));
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public Stream OpenResource(string key)
|
|
{
|
|
if (File.Exists(key))
|
|
{
|
|
return File.Open(key, FileMode.Open);
|
|
}
|
|
else if (Uri.TryCreate(key, UriKind.RelativeOrAbsolute, out Uri uri))
|
|
{
|
|
return OpenResource(uri);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
MediaHint InferMedia(Stream str, MediaHint hint)
|
|
{
|
|
if (hint != MediaHint.None)
|
|
{
|
|
return hint;
|
|
}
|
|
|
|
byte[] array = ByteArrays.Rent(4);
|
|
str.Read(array, 0, 4);
|
|
str.Position = 0;
|
|
|
|
foreach (var(type, seq) in MediaTypes)
|
|
{
|
|
if (seq.SequenceEqual(array))
|
|
return hint;
|
|
}
|
|
|
|
return MediaHint.None;
|
|
}
|
|
|
|
private readonly (MediaHint, byte[])[] MediaTypes = new (MediaHint, byte[])[] {
|
|
(MediaHint.Image, new byte[] { 0x42, 0x4d }), /* .bmp `BM` */
|
|
(MediaHint.Image, new byte[] { 0x47, 0x49, 0x46, 0x38 }), /* .gif `GIF8` */
|
|
(MediaHint.Image, new byte[] { 0xff, 0xd8, 0xff, 0xe0 }), /* .jpg (JFIF) */
|
|
(MediaHint.Image, new byte[] { 0xff, 0xd8, 0xff, 0xe1 }), /* .jpg (EXIF) */
|
|
(MediaHint.Image, new byte[] { 0x89, 0x50, 0x4e, 0x47 }), /* .png `.PNG `*/
|
|
(MediaHint.Image, new byte[] { 0x4d, 0x4d, 0x00, 0x2a }), /* .tif (motorola) */
|
|
(MediaHint.Image, new byte[] { 0x49, 0x49, 0x2a, 0x00 }), /* .tif (intel) */
|
|
(MediaHint.Font, new byte[] { 0x00, 0x01, 0x00, 0x00 }), /* .ttf */
|
|
(MediaHint.Font, new byte[] { 0x4F, 0x54, 0x54, 0x4F }), /* .otf */
|
|
};
|
|
}
|
|
}
|