/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (!disposed) { if (documentProfile != null) { documentProfile.Dispose(); documentProfile = null; } if (monitorProfile != null) { monitorProfile.Dispose(); monitorProfile = null; } if (transform != null) { transform.Dispose(); transform = null; } if (interleavedCMYKSurface != null) { interleavedCMYKSurface.Dispose(); interleavedCMYKSurface = null; } if (interleavedRGBSurface != null) { interleavedRGBSurface.Dispose(); interleavedRGBSurface = null; } disposed = true; } }
/// <summary> /// Performs color correction on the RGB image data. /// </summary> /// <param name="srcPtr">The pointer to the start of the image data..</param> /// <param name="srcRowBytes">The source row bytes.</param> /// <param name="srcColBytes">The source column bytes.</param> /// <param name="srcPlaneBytes">The source plane bytes.</param> /// <param name="origin">The origin.</param> /// <param name="destinationSurface">The destination surface.</param> /// <returns><c>true</c> if the image data was successfully converted; otherwise, <c>false</c>.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="destinationSurface"/> is null. /// </exception> public unsafe bool ColorCorrectRGB( IntPtr srcPtr, int srcRowBytes, int srcColBytes, int srcPlaneBytes, Point origin, IDisplayPixelsSurface destinationSurface) { if (destinationSurface == null) { throw new ArgumentNullException(nameof(destinationSurface)); } if (transform == null) { return(false); } if (srcColBytes == 1) { // As the Windows Color System APIs do not support planar order image data we have to convert the // image data to interleaved and then use a second surface for the final color correction. if (interleavedRGBSurface == null || interleavedRGBSurface.Width != destinationSurface.Width || interleavedRGBSurface.Height != destinationSurface.Height) { interleavedRGBSurface?.Dispose(); interleavedRGBSurface = new SurfaceBGR24(destinationSurface.Width, destinationSurface.Height); } int top = origin.Y; int left = origin.X; int bottom = top + interleavedRGBSurface.Height; int right = left + interleavedRGBSurface.Width; byte *baseAddr = (byte *)srcPtr; int greenPlaneOffset = srcPlaneBytes; int bluePlaneOffset = srcPlaneBytes * 2; for (int y = top; y < bottom; y++) { byte *redPlane = baseAddr + (y * srcRowBytes) + left; byte *greenPlane = redPlane + greenPlaneOffset; byte *bluePlane = redPlane + bluePlaneOffset; byte *dst = interleavedRGBSurface.GetRowAddressUnchecked(y - top); for (int x = left; x < right; x++) { dst[2] = *redPlane; dst[1] = *greenPlane; dst[0] = *bluePlane; redPlane++; greenPlane++; bluePlane++; dst += 3; } } return(UnsafeNativeMethods.Mscms.TranslateBitmapBits( transform, interleavedRGBSurface.Scan0.Pointer, interleavedRGBSurface.MscmsFormat, (uint)destinationSurface.Width, (uint)destinationSurface.Height, (uint)interleavedRGBSurface.Stride, destinationSurface.Scan0.Pointer, destinationSurface.MscmsFormat, (uint)destinationSurface.Stride, IntPtr.Zero, IntPtr.Zero )); } else { NativeEnums.Mscms.BMFORMAT srcFormat; switch (srcColBytes) { case 3: srcFormat = NativeEnums.Mscms.BMFORMAT.BM_BGRTRIPLETS; break; case 4: srcFormat = NativeEnums.Mscms.BMFORMAT.BM_xBGRQUADS; break; default: throw new InvalidOperationException("Unsupported column bytes value."); } byte *srcDataStart = (byte *)srcPtr + (origin.Y * srcRowBytes) + (origin.X * srcColBytes); return(UnsafeNativeMethods.Mscms.TranslateBitmapBits( transform, (IntPtr)srcDataStart, srcFormat, (uint)destinationSurface.Width, (uint)destinationSurface.Height, (uint)srcRowBytes, destinationSurface.Scan0.Pointer, destinationSurface.MscmsFormat, (uint)destinationSurface.Stride, IntPtr.Zero, IntPtr.Zero )); } }