Esempio n. 1
0
        /// <summary>
        /// Copies the image to a destination pointer.
        /// </summary>
        /// <param name="destination">The destination pointer to copy the image to.</param>
        /// <param name="width">The destination width.</param>
        /// <param name="height">The destination height.</param>
        /// <param name="stride">The destination stride.</param>
        /// <param name="pixelFormat">The destination pixel format.</param>
        public void CopyTo(IntPtr destination, int width, int height, int stride, PixelFormat pixelFormat)
        {
            if ((this.width != width) || (this.height != height))
            {
                throw new InvalidOperationException("Destination image has different size.");
            }

            // Check if pixel formats are the same. If so, do a straight up copy
            if (this.PixelFormat == pixelFormat)
            {
                if (this.stride == stride)
                {
                    this.image.CopyTo(destination, stride * height);
                }
                else
                {
                    unsafe
                    {
                        int copyLength = (this.stride < stride) ? this.stride : stride;

                        byte *src = (byte *)this.image.Data.ToPointer();
                        byte *dst = (byte *)destination.ToPointer();

                        // copy line by line
                        for (int i = 0; i < this.height; i++)
                        {
                            Buffer.MemoryCopy(src, dst, copyLength, copyLength);

                            dst += stride;
                            src += this.stride;
                        }
                    }
                }
            }
            else if ((this.pixelFormat == PixelFormat.BGR_24bpp) &&
                     (pixelFormat == PixelFormat.BGRX_32bpp ||
                      pixelFormat == PixelFormat.BGRA_32bpp))
            {
                unsafe
                {
                    byte *src = (byte *)this.image.Data.ToPointer();
                    byte *dst = (byte *)destination.ToPointer();
                    Parallel.For(0, this.Height, i =>
                    {
                        byte *srcCopy = src + (this.stride * i);
                        byte *dstCopy = dst + (stride * i);
                        for (int j = 0; j < this.width; j++)
                        {
                            *dstCopy++ = *srcCopy++;
                            *dstCopy++ = *srcCopy++;
                            *dstCopy++ = *srcCopy++;
                            *dstCopy++ = 255;
                        }
                    });
                }
            }
            else if ((this.pixelFormat == PixelFormat.BGRX_32bpp) &&
                     (pixelFormat == PixelFormat.BGR_24bpp))
            {
                unsafe
                {
                    byte *src = (byte *)this.image.Data.ToPointer();
                    byte *dst = (byte *)destination.ToPointer();
                    Parallel.For(0, this.Height, i =>
                    {
                        byte *srcCopy = src + (this.stride * i);
                        byte *dstCopy = dst + (stride * i);
                        for (int j = 0; j < this.width; j++)
                        {
                            *dstCopy++ = *srcCopy++;
                            *dstCopy++ = *srcCopy++;
                            *dstCopy++ = *srcCopy++;
                            srcCopy++;
                        }
                    });
                }
            }
            else if ((this.pixelFormat == PixelFormat.BGR_24bpp) &&
                     (pixelFormat == PixelFormat.Gray_8bpp))
            {
                unsafe
                {
                    byte *src = (byte *)this.image.Data.ToPointer();
                    byte *dst = (byte *)destination.ToPointer();

                    Parallel.For(0, this.Height, i =>
                    {
                        byte *srcCopy = src + (this.stride * i);
                        byte *dstCopy = dst + (stride * i);
                        for (int j = 0; j < this.width; j++)
                        {
                            *dstCopy++ = Operators.Rgb2Gray(*srcCopy, *(srcCopy + 1), *(srcCopy + 2));
                            srcCopy   += 3;
                        }
                    });
                }
            }
            else
            {
                this.CopyImageSlow(this.image.Data, this.pixelFormat, destination, stride, pixelFormat);
            }
        }
Esempio n. 2
0
        private void CopyImageSlow(IntPtr sourceIntPtr, PixelFormat sourceFormat, IntPtr destinationIntPtr, int destinationStride, PixelFormat destinationFormat)
        {
            unsafe
            {
                int srcBytesPerPixel = sourceFormat.GetBytesPerPixel();
                int dstBytesPerPixel = destinationFormat.GetBytesPerPixel();
                Parallel.For(
                    0,
                    this.Height,
                    i =>
                {
                    byte *srcCol = (byte *)sourceIntPtr.ToPointer() + (i * this.stride);
                    byte *dstCol = (byte *)destinationIntPtr.ToPointer() + (i * destinationStride);
                    for (int j = 0; j < this.width; j++)
                    {
                        int red   = 0;
                        int green = 0;
                        int blue  = 0;
                        int alpha = 255;
                        switch (sourceFormat)
                        {
                        case PixelFormat.Gray_8bpp:
                            red = green = blue = srcCol[0];
                            break;

                        case PixelFormat.Gray_16bpp:
                            red = green = blue = ((ushort *)srcCol)[0];
                            break;

                        case PixelFormat.BGR_24bpp:
                            blue  = srcCol[0];
                            green = srcCol[1];
                            red   = srcCol[2];
                            break;

                        case PixelFormat.BGRX_32bpp:
                            blue  = srcCol[0];
                            green = srcCol[1];
                            red   = srcCol[2];
                            break;

                        case PixelFormat.BGRA_32bpp:
                            blue  = srcCol[0];
                            green = srcCol[1];
                            red   = srcCol[2];
                            alpha = srcCol[3];
                            break;

                        case PixelFormat.RGBA_64bpp:
                            red   = ((ushort *)srcCol)[0];
                            green = ((ushort *)srcCol)[1];
                            blue  = ((ushort *)srcCol)[2];
                            alpha = ((ushort *)srcCol)[3];
                            break;

                        case PixelFormat.Undefined:
                        default:
                            throw new ArgumentException(ExceptionDescriptionUnexpectedPixelFormat);
                        }

                        switch (destinationFormat)
                        {
                        case PixelFormat.Gray_8bpp:
                            dstCol[0] = Operators.Rgb2Gray((byte)red, (byte)green, (byte)blue);
                            break;

                        case PixelFormat.Gray_16bpp:
                            ((ushort *)dstCol)[0] = Operators.Rgb2Gray((ushort)red, (ushort)green, (ushort)blue);
                            break;

                        case PixelFormat.BGR_24bpp:
                        case PixelFormat.BGRX_32bpp:
                            dstCol[0] = (byte)blue;
                            dstCol[1] = (byte)green;
                            dstCol[2] = (byte)red;
                            break;

                        case PixelFormat.BGRA_32bpp:
                            dstCol[0] = (byte)blue;
                            dstCol[1] = (byte)green;
                            dstCol[2] = (byte)red;
                            dstCol[3] = (byte)alpha;
                            break;

                        case PixelFormat.RGBA_64bpp:
                            ((ushort *)dstCol)[0] = (ushort)red;
                            ((ushort *)dstCol)[1] = (ushort)green;
                            ((ushort *)dstCol)[2] = (ushort)blue;
                            ((ushort *)dstCol)[3] = (ushort)alpha;
                            break;

                        case PixelFormat.Undefined:
                        default:
                            throw new ArgumentException(ExceptionDescriptionUnexpectedPixelFormat);
                        }

                        srcCol += srcBytesPerPixel;
                        dstCol += dstBytesPerPixel;
                    }
                });
            }
        }
Esempio n. 3
0
        private void CopyImageSlow(IntPtr sourceIntPtr, PixelFormat sourceFormat, IntPtr destinationIntPtr, int destinationStride, PixelFormat destinationFormat)
        {
            unsafe
            {
                int srcBytesPerPixel = sourceFormat.GetBytesPerPixel();
                int dstBytesPerPixel = destinationFormat.GetBytesPerPixel();
                Parallel.For(
                    0,
                    this.Height,
                    i =>
                {
                    byte *srcCol = (byte *)sourceIntPtr.ToPointer() + (i * this.stride);
                    byte *dstCol = (byte *)destinationIntPtr.ToPointer() + (i * destinationStride);
                    for (int j = 0; j < this.width; j++)
                    {
                        int red;
                        int green;
                        int blue;
                        int alpha;
                        int bits;
                        switch (sourceFormat)
                        {
                        case PixelFormat.Gray_8bpp:
                            red   = green = blue = srcCol[0];
                            alpha = 255;
                            bits  = 8;
                            break;

                        case PixelFormat.Gray_16bpp:
                            red   = green = blue = ((ushort *)srcCol)[0];
                            alpha = 65535;
                            bits  = 16;
                            break;

                        case PixelFormat.BGR_24bpp:
                        case PixelFormat.BGRX_32bpp:
                            blue  = srcCol[0];
                            green = srcCol[1];
                            red   = srcCol[2];
                            alpha = 255;
                            bits  = 8;
                            break;

                        case PixelFormat.BGRA_32bpp:
                            blue  = srcCol[0];
                            green = srcCol[1];
                            red   = srcCol[2];
                            alpha = srcCol[3];
                            bits  = 8;
                            break;

                        case PixelFormat.RGB_24bpp:
                            red   = srcCol[0];
                            green = srcCol[1];
                            blue  = srcCol[2];
                            alpha = 255;
                            bits  = 8;
                            break;

                        case PixelFormat.RGBA_64bpp:
                            red   = ((ushort *)srcCol)[0];
                            green = ((ushort *)srcCol)[1];
                            blue  = ((ushort *)srcCol)[2];
                            alpha = ((ushort *)srcCol)[3];
                            bits  = 16;
                            break;

                        case PixelFormat.Undefined:
                        default:
                            throw new ArgumentException(ExceptionDescriptionUnexpectedPixelFormat);
                        }

                        // Convert from 8-bits-per-channel (0-255) to 16-bits-per-channel (0-65535) and visa versa when needed.
                        switch (destinationFormat)
                        {
                        case PixelFormat.Gray_8bpp:
                        case PixelFormat.BGR_24bpp:
                        case PixelFormat.BGRX_32bpp:
                        case PixelFormat.BGRA_32bpp:
                        case PixelFormat.RGB_24bpp:
                            if (bits == 16)
                            {
                                red   >>= 8;
                                green >>= 8;
                                blue  >>= 8;
                                alpha >>= 8;
                            }

                            break;

                        case PixelFormat.Gray_16bpp:
                        case PixelFormat.RGBA_64bpp:
                            if (bits == 8)
                            {
                                red   = (red << 8) | red;
                                green = (green << 8) | green;
                                blue  = (blue << 8) | blue;
                                alpha = (alpha << 8) | alpha;
                            }

                            break;
                        }

                        switch (destinationFormat)
                        {
                        case PixelFormat.Gray_8bpp:
                            dstCol[0] = Operators.Rgb2Gray((byte)red, (byte)green, (byte)blue);
                            break;

                        case PixelFormat.Gray_16bpp:
                            ((ushort *)dstCol)[0] = Operators.Rgb2Gray((ushort)red, (ushort)green, (ushort)blue);
                            break;

                        case PixelFormat.BGR_24bpp:
                        case PixelFormat.BGRX_32bpp:
                            dstCol[0] = (byte)blue;
                            dstCol[1] = (byte)green;
                            dstCol[2] = (byte)red;
                            break;

                        case PixelFormat.BGRA_32bpp:
                            dstCol[0] = (byte)blue;
                            dstCol[1] = (byte)green;
                            dstCol[2] = (byte)red;
                            dstCol[3] = (byte)alpha;
                            break;

                        case PixelFormat.RGB_24bpp:
                            dstCol[0] = (byte)red;
                            dstCol[1] = (byte)green;
                            dstCol[2] = (byte)blue;
                            break;

                        case PixelFormat.RGBA_64bpp:
                            ((ushort *)dstCol)[0] = (ushort)red;
                            ((ushort *)dstCol)[1] = (ushort)green;
                            ((ushort *)dstCol)[2] = (ushort)blue;
                            ((ushort *)dstCol)[3] = (ushort)alpha;
                            break;

                        case PixelFormat.Undefined:
                        default:
                            throw new ArgumentException(ExceptionDescriptionUnexpectedPixelFormat);
                        }

                        srcCol += srcBytesPerPixel;
                        dstCol += dstBytesPerPixel;
                    }
                });
            }
        }