diff --git a/src/OpenJpegDotNet/Image.cs b/src/OpenJpegDotNet/Image.cs
index aa22ebc..fb0d8e5 100644
--- a/src/OpenJpegDotNet/Image.cs
+++ b/src/OpenJpegDotNet/Image.cs
@@ -184,10 +184,11 @@ public byte[] IccProfile
///
/// Converts this to a GDI+ .
///
+ /// Export alpha channel
/// A that represents the converted .
/// This object is disposed.
/// This object is not supported.
- public Bitmap ToBitmap()
+ public Bitmap ToBitmap(bool alpha = true)
{
this.ThrowIfDisposed();
@@ -206,14 +207,6 @@ public Bitmap ToBitmap()
throw new NotSupportedException("This object is not supported.");
}
- if (channel != 3 && channel != 1)
- {
- if (planes != IntPtr.Zero)
- NativeMethods.stdlib_free(planes);
-
- throw new NotSupportedException("This object is not supported.");
- }
-
Bitmap bitmap = null;
BitmapData bitmapData = null;
@@ -271,11 +264,45 @@ public Bitmap ToBitmap()
}
}
break;
+ case 4:
+ {
+ bitmap = new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb);
+ var rect = new Rectangle(0, 0, (int)width, (int)height);
+ bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
+ var scan0 = bitmapData.Scan0;
+ var stride = bitmapData.Stride;
+
+ unsafe
+ {
+ var pSrc = (byte*)planes;
+ var pDest = (byte*)scan0;
+ var gap = stride - width * channel;
+ var size = width * height;
+ for (var y = 0; y < height; y++)
+ {
+ for (var x = 0; x < width; x++)
+ {
+ pDest[3] = alpha ? pSrc[0 + size * 3] : (byte)255;
+ pDest[2] = pSrc[0];
+ pDest[1] = pSrc[0 + size];
+ pDest[0] = pSrc[0 + size * 2];
+
+ pSrc += 1;
+ pDest += channel;
+ }
+
+ pDest += gap;
+ }
+ }
+ }
+ break;
+ default:
+ throw new NotSupportedException($"Unsupported number of channels: ${channel}.");
}
break;
default:
- throw new NotSupportedException("This object is not supported.");
+ throw new NotSupportedException($"Unsupported pixel depth: ${pixel}.");
}
}
catch
@@ -301,6 +328,7 @@ public Bitmap ToBitmap()
///
/// Converts this to a .
///
+ /// Export alpha channel
/// A that represents the converted .
/// This object is not supported.
public RawBitmap ToRawBitmap()
@@ -322,14 +350,6 @@ public RawBitmap ToRawBitmap()
throw new NotSupportedException("This object is not supported.");
}
- if (channel != 3 && channel != 1)
- {
- if (planes != IntPtr.Zero)
- NativeMethods.stdlib_free(planes);
-
- throw new NotSupportedException("This object is not supported.");
- }
-
var raw = new byte[width * height * channel];
try
@@ -382,11 +402,39 @@ public RawBitmap ToRawBitmap()
}
}
break;
+ case 4:
+ {
+ unsafe
+ {
+ fixed (byte* dst = &raw[0])
+ {
+ var pSrc = (byte*)planes;
+ var pDest = dst;
+ var size = width * height;
+ for (var y = 0; y < height; y++)
+ {
+ for (var x = 0; x < width; x++)
+ {
+ pDest[3] = alpha ? pSrc[0 + size * 3] : (byte)255;
+ pDest[2] = pSrc[0];
+ pDest[1] = pSrc[0 + size];
+ pDest[0] = pSrc[0 + size * 2];
+
+ pSrc += 1;
+ pDest += channel;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default:
+ throw new NotSupportedException($"Unsupported number of channels: ${channel}.");
}
break;
default:
- throw new NotSupportedException("This object is not supported.");
+ throw new NotSupportedException($"Unsupported pixel depth: ${pixel}.");
}
}
finally
@@ -419,4 +467,4 @@ protected override void DisposeUnmanaged()
}
-}
\ No newline at end of file
+}