public static IBitmapSource FromPointer(IntPtr data, long length) { MemoryBitmapSource b; var decoder = LibFlifNative.FlifCreateDecoder(); try { if (LibFlifNative.FlifDecoderDecodeMemory(decoder, data, (UIntPtr)length) == 0) { return(null); } var image = LibFlifNative.FlifDecoderGetImage(decoder, UIntPtr.Zero); var width = LibFlifNative.FlifImageGetWidth(image); var height = LibFlifNative.FlifImageGetHeight(image); var bitDepth = LibFlifNative.FlifImageGetDepth(image); if (bitDepth > 8) { b = new MemoryBitmapSource(width, height, 16, 4); for (var line = 0; line < height; line++) { var position = b.Scan0 + b.Stride * line; LibFlifNative.FlifImageReadRowRgba16(image, line, position, (UIntPtr)b.Stride); } } else { b = new MemoryBitmapSource(width, height, 8, 4); for (var line = 0; line < height; line++) { var position = b.Scan0 + b.Stride * line; LibFlifNative.FlifImageReadRowRgba8(image, line, position, (UIntPtr)b.Stride); } PixelTool.BGRA2RGBA(b.Scan0, (UIntPtr)(width * height)); } LibFlifNative.FlifDestroyImage(image); } finally { // LibFlifNative.FlifDestroyDecoder(decoder); } return(b); }
public static unsafe IBitmapSource FromPointer(IntPtr data, long length) { var ctx = UIntPtr.Zero; var imageHandle = UIntPtr.Zero; var options = UIntPtr.Zero; var image = UIntPtr.Zero; MemoryBitmapSource b; try { ctx = LibHeifNative.HeifContextAlloc(); var err = LibHeifNative.HeifContextReadFromMemoryWithoutCopy(ctx, data, (UIntPtr)length, UIntPtr.Zero); if (CheckErrPtr(err)) { throw new Exception("Failed."); } var imageCount = LibHeifNative.HeifContextGetNumberOfTopLevelImages(ctx); if (imageCount == 0) { throw new Exception("Failed."); } var imageIDs = new heif_item_id[imageCount]; fixed(heif_item_id *ptr = imageIDs) { imageCount = LibHeifNative.HeifContextGetListOfTopLevelImageIDs(ctx, (UIntPtr)ptr, imageCount); } err = LibHeifNative.HeifContextGetImageHandle(ctx, imageIDs[0], ref imageHandle); if (CheckErrPtr(err)) { throw new Exception("Failed."); } var depth = LibHeifNative.HeifImageHandleGetLumaBitsPerPixel(imageHandle); if (depth < 0) { throw new Exception("Failed."); } options = LibHeifNative.HeifDecodingOptionsAlloc(); var hasAlpha = LibHeifNative.HeifImageHandleHasAlphaChannel(imageHandle) != 0; HeifChroma chroma; int targetDepth; int targetChannel; if (depth <= 8) { chroma = HeifChroma.HeifChromaInterleavedRgba; targetDepth = 8; targetChannel = 4; } else if (hasAlpha) { chroma = HeifChroma.HeifChromaInterleavedRrggbbaaLe; targetDepth = 16; targetChannel = 4; } else { chroma = HeifChroma.HeifChromaInterleavedRrggbbLe; targetDepth = 16; targetChannel = 3; } err = LibHeifNative.HeifDecodeImage(imageHandle, ref image, HeifColorspace.HeifColorspaceRgb, chroma, options); if (CheckErrPtr(err) || image == UIntPtr.Zero) { throw new Exception("Failed."); } var width = LibHeifNative.HeifImageGetWidth(image, HeifChannel.HeifChannelInterleaved); var height = LibHeifNative.HeifImageGetHeight(image, HeifChannel.HeifChannelInterleaved); b = new MemoryBitmapSource(width, height, targetDepth, targetChannel); var strideSource = 0; var strideDest = b.Stride; var raw = LibHeifNative.HeifImageGetPlaneReadonly(image, HeifChannel.HeifChannelInterleaved, ref strideSource); var ptrBegin = b.Scan0; if (strideSource != strideDest) { for (var line = 0; line < height; line++) { var src = raw + line * strideSource; var dst = ptrBegin + line * strideDest; Buffer.MemoryCopy(src.ToPointer(), dst.ToPointer(), strideSource, strideDest); } } else { Buffer.MemoryCopy(raw.ToPointer(), ptrBegin.ToPointer(), strideSource * height, strideDest * height); } Console.WriteLine(); // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (chroma) { case HeifChroma.HeifChromaInterleavedRgba: PixelTool.BGRA2RGBA(b.Scan0, (UIntPtr)(width * height)); break; case HeifChroma.HeifChromaInterleavedRrggbbaaLe: PixelTool.DEPTHCONVERT(b.Scan0, (UIntPtr)(width * height * 4), (UIntPtr)depth); break; case HeifChroma.HeifChromaInterleavedRrggbbLe: PixelTool.DEPTHCONVERT(b.Scan0, (UIntPtr)(width * height * 3), (UIntPtr)depth); break; } } finally { if (ctx != UIntPtr.Zero) { LibHeifNative.HeifContextFree(ctx); } if (imageHandle != UIntPtr.Zero) { LibHeifNative.HeifImageHandleRelease(imageHandle); } if (options != UIntPtr.Zero) { LibHeifNative.HeifDecodingOptionsFree(options); } if (image != UIntPtr.Zero) { LibHeifNative.HeifImageRelease(image); } } return(b); }