50 lines
1.9 KiB
C#
50 lines
1.9 KiB
C#
using Dalamud.Interface;
|
|
using Dalamud.Interface.Internal;
|
|
using Dalamud.Memory;
|
|
using WebP.Net;
|
|
using WebP.Net.Natives;
|
|
using WebP.Net.Natives.Enums;
|
|
using WebP.Net.Natives.Structs;
|
|
|
|
namespace Screenie.Util;
|
|
|
|
internal static class WebPHelper {
|
|
internal static async Task<IDalamudTextureWrap?> LoadAsync(UiBuilder builder, byte[] imageBytes) {
|
|
int width;
|
|
int height;
|
|
byte[] rgba;
|
|
|
|
unsafe {
|
|
fixed (byte* imagePtr = imageBytes) {
|
|
var features = default(WebPBitstreamFeatures);
|
|
var vp8StatusCode = Native.WebPGetFeatures((nint) imagePtr, imageBytes.Length, ref features);
|
|
if (vp8StatusCode != Vp8StatusCode.Ok) {
|
|
Plugin.Log.Warning($"could not get webp features: {Enum.GetName(vp8StatusCode)}");
|
|
return null;
|
|
}
|
|
|
|
width = features.Width;
|
|
height = features.Height;
|
|
rgba = new byte[width * height * 4];
|
|
|
|
var decoderConfig = default(WebPDecoderConfig);
|
|
decoderConfig.input = features;
|
|
decoderConfig.output.colorSpace = WebpCspMode.ModeRgba;
|
|
decoderConfig.output.isExternalMemory = 1;
|
|
decoderConfig.output.u.Rgba.size = (nuint) rgba.Length;
|
|
decoderConfig.output.u.Rgba.stride = height * 4;
|
|
fixed (byte* rgbaPtr = rgba) {
|
|
decoderConfig.output.u.Rgba.rgba = (nint) rgbaPtr;
|
|
var code = Native.WebPDecode((nint) imagePtr, imageBytes.Length, ref decoderConfig);
|
|
if (code != Vp8StatusCode.Ok) {
|
|
Plugin.Log.Warning($"could not decode webp: {Enum.GetName(code)}");
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return await builder.LoadImageRawAsync(rgba, width, height, 4);
|
|
}
|
|
}
|