Пример #1
0
        /// <summary>
        /// Performs color correction on the specified 8-bit gray scale image data and converts it to RGB.
        /// </summary>
        /// <param name="srcPtr">The pointer to the start of the gray scale image data.</param>
        /// <param name="srcStride">The stride of the gray scale image data.</param>
        /// <param name="origin">The starting row and column offset in the image data buffer.</param>
        /// <param name="destSurface">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="destSurface"/> is null.</exception>
        public unsafe bool ColorCorrectGrayScale(IntPtr srcPtr, int srcStride, Point origin, IDisplayPixelsSurface destSurface)
        {
            if (destSurface == null)
            {
                throw new ArgumentNullException(nameof(destSurface));
            }

            if (transform == null)
            {
                return(false);
            }

            byte *srcDataStart = (byte *)srcPtr + (origin.Y * srcStride) + origin.X;

            return(UnsafeNativeMethods.Mscms.TranslateBitmapBits(
                       transform,
                       (IntPtr)srcDataStart,
                       NativeEnums.Mscms.BMFORMAT.BM_GRAY,
                       (uint)destSurface.Width,
                       (uint)destSurface.Height,
                       (uint)srcStride,
                       destSurface.Scan0.Pointer,
                       destSurface.MscmsFormat,
                       (uint)destSurface.Stride,
                       IntPtr.Zero,
                       IntPtr.Zero
                       ));
        }
Пример #2
0
        /// <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
                           ));
            }
        }
Пример #3
0
        /// <summary>
        /// Performs color correction on the specified 8-bit CMYK image data and converts it to RGB..
        /// </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>
        public unsafe bool ColorCorrectCMYK(
            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 (interleavedCMYKSurface == null ||
                    interleavedCMYKSurface.Width != destinationSurface.Width ||
                    interleavedCMYKSurface.Height != destinationSurface.Height)
                {
                    interleavedCMYKSurface?.Dispose();
                    interleavedCMYKSurface = new SurfaceCMYK32(destinationSurface.Width, destinationSurface.Height);
                }

                int top    = origin.Y;
                int left   = origin.X;
                int bottom = top + interleavedCMYKSurface.Height;
                int right  = left + interleavedCMYKSurface.Width;

                byte *baseAddr = (byte *)srcPtr;

                int magentaPlaneOffset = srcPlaneBytes;
                int yellowPlaneOffset  = magentaPlaneOffset + srcPlaneBytes;
                int blackPlaneOffset   = yellowPlaneOffset + srcPlaneBytes;

                for (int y = top; y < bottom; y++)
                {
                    byte *cyanPlane    = baseAddr + (y * srcRowBytes) + left;
                    byte *magentaPlane = cyanPlane + magentaPlaneOffset;
                    byte *yellowPlane  = cyanPlane + yellowPlaneOffset;
                    byte *blackPlane   = cyanPlane + blackPlaneOffset;

                    byte *dst = interleavedCMYKSurface.GetRowAddressUnchecked(y - top);

                    for (int x = left; x < right; x++)
                    {
                        dst[0] = *cyanPlane;
                        dst[1] = *magentaPlane;
                        dst[2] = *yellowPlane;
                        dst[3] = *blackPlane;

                        cyanPlane++;
                        magentaPlane++;
                        yellowPlane++;
                        blackPlane++;
                        dst += 4;
                    }
                }

                return(UnsafeNativeMethods.Mscms.TranslateBitmapBits(
                           transform,
                           interleavedCMYKSurface.Scan0.Pointer,
                           interleavedCMYKSurface.MscmsFormat,
                           (uint)destinationSurface.Width,
                           (uint)destinationSurface.Height,
                           (uint)interleavedCMYKSurface.Stride,
                           destinationSurface.Scan0.Pointer,
                           destinationSurface.MscmsFormat,
                           (uint)destinationSurface.Stride,
                           IntPtr.Zero,
                           IntPtr.Zero
                           ));
            }
            else
            {
                byte *srcDataStart = (byte *)srcPtr + (origin.Y * srcRowBytes) + (origin.X * srcColBytes);

                return(UnsafeNativeMethods.Mscms.TranslateBitmapBits(
                           transform,
                           (IntPtr)srcDataStart,
                           NativeEnums.Mscms.BMFORMAT.BM_KYMCQUADS,
                           (uint)destinationSurface.Width,
                           (uint)destinationSurface.Height,
                           (uint)srcRowBytes,
                           destinationSurface.Scan0.Pointer,
                           destinationSurface.MscmsFormat,
                           (uint)destinationSurface.Stride,
                           IntPtr.Zero,
                           IntPtr.Zero
                           ));
            }
        }