private short WriteBasePixels(IntPtr port, ref VRect writeRect, PixelMemoryDesc srcDesc)
        {
#if DEBUG
            DebugUtils.Ping(DebugFlags.ChannelPorts, string.Format("port: {0}, rect: {1}", port.ToString(), writeRect.ToString()));
#endif
            return(PSError.memFullErr);
        }
Beispiel #2
0
        private unsafe short WriteBasePixels(IntPtr port, VRect *writeRect, PixelMemoryDesc srcDesc)
        {
#if DEBUG
            DebugUtils.Ping(DebugFlags.ChannelPorts, string.Format("port: {0}, rect: {1}", port.ToString(), DebugUtils.PointerToString(writeRect)));
#endif
            if (writeRect == null)
            {
                return(PSError.paramErr);
            }

            return(PSError.memFullErr);
        }
        private static unsafe void FillSelectionMask(PixelMemoryDesc destiniation, SurfaceGray8 source, VRect srcRect)
        {
            byte *dstPtr = (byte *)destiniation.data.ToPointer();
            int   stride = destiniation.rowBits / 8;
            int   bpp    = destiniation.colBits / 8;
            int   offset = destiniation.bitOffset / 8;

            for (int y = srcRect.top; y < srcRect.bottom; y++)
            {
                byte *src = source.GetPointAddressUnchecked(srcRect.left, y);
                byte *dst = dstPtr + (y * stride) + offset;
                for (int x = srcRect.left; x < srcRect.right; x++)
                {
                    *dst = *src;

                    src++;
                    dst += bpp;
                }
            }
        }
        private static unsafe void FillChannelData(int channel, PixelMemoryDesc destiniation, SurfaceBase source, VRect srcRect, ImageModes mode)
        {
            byte *dstPtr = (byte *)destiniation.data.ToPointer();
            int   stride = destiniation.rowBits / 8;
            int   bpp    = destiniation.colBits / 8;
            int   offset = destiniation.bitOffset / 8;

            switch (mode)
            {
            case ImageModes.GrayScale:

                for (int y = srcRect.top; y < srcRect.bottom; y++)
                {
                    byte *src = source.GetPointAddressUnchecked(srcRect.left, y);
                    byte *dst = dstPtr + (y * stride) + offset;
                    for (int x = srcRect.left; x < srcRect.right; x++)
                    {
                        *dst = *src;

                        src++;
                        dst += bpp;
                    }
                }

                break;

            case ImageModes.RGB:

                for (int y = srcRect.top; y < srcRect.bottom; y++)
                {
                    byte *src = source.GetPointAddressUnchecked(srcRect.left, y);
                    byte *dst = dstPtr + (y * stride) + offset;
                    for (int x = srcRect.left; x < srcRect.right; x++)
                    {
                        switch (channel)
                        {
                        case PSConstants.ChannelPorts.Red:
                            *dst = src[2];
                            break;

                        case PSConstants.ChannelPorts.Green:
                            *dst = src[1];
                            break;

                        case PSConstants.ChannelPorts.Blue:
                            *dst = src[0];
                            break;

                        case PSConstants.ChannelPorts.Alpha:
                            *dst = src[3];
                            break;
                        }
                        src += 4;
                        dst += bpp;
                    }
                }

                break;

            case ImageModes.Gray16:

                for (int y = srcRect.top; y < srcRect.bottom; y++)
                {
                    ushort *src = (ushort *)source.GetPointAddressUnchecked(srcRect.left, y);
                    ushort *dst = (ushort *)(dstPtr + (y * stride) + offset);
                    for (int x = srcRect.left; x < srcRect.right; x++)
                    {
                        *dst = *src;

                        src++;
                        dst += bpp;
                    }
                }

                break;

            case ImageModes.RGB48:

                for (int y = srcRect.top; y < srcRect.bottom; y++)
                {
                    ushort *src = (ushort *)source.GetPointAddressUnchecked(srcRect.left, y);
                    ushort *dst = (ushort *)(dstPtr + (y * stride) + offset);
                    for (int x = srcRect.left; x < srcRect.right; x++)
                    {
                        switch (channel)
                        {
                        case PSConstants.ChannelPorts.Red:
                            *dst = src[2];
                            break;

                        case PSConstants.ChannelPorts.Green:
                            *dst = src[1];
                            break;

                        case PSConstants.ChannelPorts.Blue:
                            *dst = src[0];
                            break;

                        case PSConstants.ChannelPorts.Alpha:
                            *dst = src[3];
                            break;
                        }
                        src += 4;
                        dst += bpp;
                    }
                }

                break;
            }
        }
        private unsafe short ReadPixelsProc(IntPtr port, ref PSScaling scaling, ref VRect writeRect, ref PixelMemoryDesc destination, ref VRect wroteRect)
        {
#if DEBUG
            DebugUtils.Ping(DebugFlags.ChannelPorts, string.Format("port: {0}, rect: {1}", port.ToString(), writeRect.ToString()));
#endif

            if (destination.depth != 8 && destination.depth != 16)
            {
                return(PSError.errUnsupportedDepth);
            }

            // The offsets must be aligned to a System.Byte.
            if ((destination.bitOffset % 8) != 0)
            {
                return(PSError.errUnsupportedBitOffset);
            }

            if ((destination.colBits % 8) != 0)
            {
                return(PSError.errUnsupportedColBits);
            }

            if ((destination.rowBits % 8) != 0)
            {
                return(PSError.errUnsupportedRowBits);
            }

            int channel = port.ToInt32();

            if (channel < PSConstants.ChannelPorts.Gray || channel > PSConstants.ChannelPorts.SelectionMask)
            {
                return(PSError.errUnknownPort);
            }

            VRect srcRect = scaling.sourceRect;
            VRect dstRect = scaling.destinationRect;

            int         srcWidth    = srcRect.right - srcRect.left;
            int         srcHeight   = srcRect.bottom - srcRect.top;
            int         dstWidth    = dstRect.right - dstRect.left;
            int         dstHeight   = dstRect.bottom - dstRect.top;
            bool        isSelection = channel == PSConstants.ChannelPorts.SelectionMask;
            SurfaceBase source      = filterImageProvider.Source;

            if ((source.BitsPerChannel == 8 || isSelection) && destination.depth == 16)
            {
                return(PSError.errUnsupportedDepthConversion); // converting 8-bit image data to 16-bit is not supported.
            }

            if (isSelection)
            {
                if (srcWidth == dstWidth && srcHeight == dstHeight)
                {
                    FillSelectionMask(destination, filterImageProvider.Mask, srcRect);
                }
                else if (dstWidth < srcWidth || dstHeight < srcHeight) // scale down
                {
                    if ((scaledSelectionMask == null) || scaledSelectionMask.Width != dstWidth || scaledSelectionMask.Height != dstHeight)
                    {
                        if (scaledSelectionMask != null)
                        {
                            scaledSelectionMask.Dispose();
                            scaledSelectionMask = null;
                        }

                        try
                        {
                            scaledSelectionMask = new SurfaceGray8(dstWidth, dstHeight);
                            scaledSelectionMask.SuperSampleFitSurface(filterImageProvider.Mask);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillSelectionMask(destination, scaledSelectionMask, dstRect);
                }
                else if (dstWidth > srcWidth || dstHeight > srcHeight) // scale up
                {
                    if ((scaledSelectionMask == null) || scaledSelectionMask.Width != dstWidth || scaledSelectionMask.Height != dstHeight)
                    {
                        if (scaledSelectionMask != null)
                        {
                            scaledSelectionMask.Dispose();
                            scaledSelectionMask = null;
                        }

                        try
                        {
                            scaledSelectionMask = new SurfaceGray8(dstWidth, dstHeight);
                            scaledSelectionMask.BicubicFitSurface(filterImageProvider.Mask);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillSelectionMask(destination, scaledSelectionMask, dstRect);
                }
            }
            else
            {
                ImageModes mode = imageMode;

                if (source.BitsPerChannel == 16 && destination.depth == 8)
                {
                    if (ditheredChannelSurface == null)
                    {
                        short err = CreateDitheredChannelPortSurface(source);
                        if (err != PSError.noErr)
                        {
                            return(err);
                        }
                    }
                    mode = ditheredChannelImageMode;
                }

                if (srcWidth == dstWidth && srcHeight == dstHeight)
                {
                    FillChannelData(channel, destination, ditheredChannelSurface ?? source, srcRect, mode);
                }
                else if (dstWidth < srcWidth || dstHeight < srcHeight) // scale down
                {
                    if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight)
                    {
                        if (scaledChannelSurface != null)
                        {
                            scaledChannelSurface.Dispose();
                            scaledChannelSurface = null;
                        }

                        try
                        {
                            scaledChannelSurface = SurfaceFactory.CreateFromImageMode(dstWidth, dstHeight, mode);
                            scaledChannelSurface.SuperSampleFitSurface(ditheredChannelSurface ?? source);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }

#if DEBUG
                        using (System.Drawing.Bitmap bmp = scaledChannelSurface.ToGdipBitmap())
                        {
                        }
#endif
                    }

                    FillChannelData(channel, destination, scaledChannelSurface, dstRect, mode);
                }
                else if (dstWidth > srcWidth || dstHeight > srcHeight) // scale up
                {
                    if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight)
                    {
                        if (scaledChannelSurface != null)
                        {
                            scaledChannelSurface.Dispose();
                            scaledChannelSurface = null;
                        }

                        try
                        {
                            scaledChannelSurface = SurfaceFactory.CreateFromImageMode(dstWidth, dstHeight, mode);
                            scaledChannelSurface.BicubicFitSurface(ditheredChannelSurface ?? source);
                        }
                        catch (OutOfMemoryException)
                        {
                            return(PSError.memFullErr);
                        }
                    }

                    FillChannelData(channel, destination, scaledChannelSurface, dstRect, mode);
                }
            }

            wroteRect = dstRect;

            return(PSError.noErr);
        }