/// <summary>
/// Create managed image from the unmanaged.
/// </summary>
///
/// <param name="makeCopy">Make a copy of the unmanaged image or not.</param>
///
/// <returns>Returns managed copy of the unmanaged image.</returns>
///
/// <remarks><para>If the <paramref name="makeCopy"/> is set to <see langword="true"/>, then the method
/// creates a managed copy of the unmanaged image, so the managed image stays valid even when the unmanaged
/// image gets disposed. However, setting this parameter to <see langword="false"/> creates a managed image which is
/// just a wrapper around the unmanaged image. So if unmanaged image is disposed, the
/// managed image becomes no longer valid and accessing it will generate an exception.</para></remarks>
///
/// <exception cref="InvalidImagePropertiesException">The unmanaged image has some invalid properties, which results
/// in failure of converting it to managed image. This may happen if user used the
/// <see cref="UnmanagedImage(IntPtr, int, int, int, PixelFormat)"/> constructor specifying some
/// invalid parameters.</exception>
///
public Bitmap ToManagedImage(bool makeCopy)
{
Bitmap dstImage = null;
try
{
if (!makeCopy)
{
dstImage = new Bitmap(width, height, stride, pixelFormat, imageData);
if (pixelFormat == PixelFormat.Format8bppIndexed)
{
Image.SetGrayscalePalette(dstImage);
}
}
else
{
// create new image of required format
dstImage = (pixelFormat == PixelFormat.Format8bppIndexed) ?
Accord.Imaging.Image.CreateGrayscaleImage(width, height) :
new Bitmap(width, height, pixelFormat);
// lock destination bitmap data
BitmapData dstData = dstImage.LockBits(
new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite, pixelFormat);
int dstStride = dstData.Stride;
int lineSize = Math.Min(stride, dstStride);
unsafe
{
byte *dst = (byte *)dstData.Scan0.ToPointer();
byte *src = (byte *)imageData.ToPointer();
if (stride != dstStride)
{
// copy image
for (int y = 0; y < height; y++)
{
Accord.SystemTools.CopyUnmanagedMemory(dst, src, lineSize);
dst += dstStride;
src += stride;
}
}
else
{
Accord.SystemTools.CopyUnmanagedMemory(dst, src, stride * height);
}
}
// unlock destination images
dstImage.UnlockBits(dstData);
}
return(dstImage);
}
catch (Exception)
{
if (dstImage != null)
{
dstImage.Dispose();
}
throw new InvalidImagePropertiesException("The unmanaged image has some invalid properties, which results in failure of converting it to managed image.");
}
}