using System; using System.Reflection; using System.Reflection.Emit; using FreeImageAPI; namespace PDFPatcher.Processor.Imaging { static class FreeImageHelper { public static bool UseDib(this FreeImageBitmap bmp, Func handler) { if (handler != null) { var t = bmp.Tag; // ensure not disposed var dib = GetDib(bmp); dib = handler(dib); return ReplaceDib(bmp, dib); } return false; } public static FreeImageBitmap CreateFromBytes(byte[] bytes, FREE_IMAGE_LOAD_FLAGS flags = default) { return new FreeImageBitmap(new System.IO.MemoryStream(bytes), flags); } public static FreeImageBitmap CreateFromBytes(byte[] bytes, FREE_IMAGE_FORMAT format) { return new FreeImageBitmap(new System.IO.MemoryStream(bytes), format); } static readonly Func GetDib = CreateGetDibMethod(); static readonly Func ReplaceDib = CreateReplaceDibMethod(); static Func CreateGetDibMethod() { var m = new DynamicMethod("GetDib", typeof(FIBITMAP), [typeof(FreeImageBitmap)], true); var il = m.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, typeof(FreeImageBitmap).GetField("dib", BindingFlags.Instance | BindingFlags.NonPublic)); il.Emit(OpCodes.Ret); return (Func)m.CreateDelegate(typeof(Func)); } static Func CreateReplaceDibMethod() { var m = new DynamicMethod("ReplaceDib", typeof(bool), [typeof(FreeImageBitmap), typeof(FIBITMAP)], true); var il = m.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Callvirt, typeof(FreeImageBitmap).GetMethod("ReplaceDib", BindingFlags.Instance | BindingFlags.NonPublic), null); il.Emit(OpCodes.Ret); return (Func)m.CreateDelegate(typeof(Func)); } } }