private static unsafe void FillChannelData(int channel, PixelMemoryDesc *destiniation, Surface 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++) { ColorBgra *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->R; break; case PSConstants.ChannelPorts.Green: *dst = src->G; break; case PSConstants.ChannelPorts.Blue: *dst = src->B; break; case PSConstants.ChannelPorts.Alpha: *dst = src->A; break; } src++; dst += bpp; } } }
private static unsafe void FillSelectionMask(PixelMemoryDesc *destiniation, MaskSurface 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 unsafe short ReadPixelsProc(IntPtr port, PSScaling *scaling, VRect *writeRect, PixelMemoryDesc *destination, VRect *wroteRect) { #if DEBUG DebugUtils.Ping(DebugFlags.ChannelPorts, string.Format("port: {0}, rect: {1}", port.ToString(), DebugUtils.PointerToString(writeRect))); #endif if (scaling == null || writeRect == null || destination == null) { return(PSError.paramErr); } if (destination->depth != 8) { return(PSError.errUnsupportedDepth); } 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.Red || 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; if (channel == PSConstants.ChannelPorts.SelectionMask) { 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; } scaledSelectionMask = new MaskSurface(dstWidth, dstHeight); scaledSelectionMask.SuperSampleFitSurface(filterImageProvider.Mask); } 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; } scaledSelectionMask = new MaskSurface(dstWidth, dstHeight); scaledSelectionMask.BicubicFitSurface(filterImageProvider.Mask); } FillSelectionMask(destination, scaledSelectionMask, dstRect); } } else { if (srcWidth == dstWidth && srcHeight == dstHeight) { FillChannelData(channel, destination, filterImageProvider.Source, srcRect); } else if (dstWidth < srcWidth || dstHeight < srcHeight) // scale down { if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight) { if (scaledChannelSurface != null) { scaledChannelSurface.Dispose(); scaledChannelSurface = null; } scaledChannelSurface = new Surface(dstWidth, dstHeight); scaledChannelSurface.SuperSampleFitSurface(filterImageProvider.Source); } FillChannelData(channel, destination, scaledChannelSurface, dstRect); } else if (dstWidth > srcWidth || dstHeight > srcHeight) // scale up { if ((scaledChannelSurface == null) || scaledChannelSurface.Width != dstWidth || scaledChannelSurface.Height != dstHeight) { if (scaledChannelSurface != null) { scaledChannelSurface.Dispose(); scaledChannelSurface = null; } scaledChannelSurface = new Surface(dstWidth, dstHeight); scaledChannelSurface.BicubicFitSurface(filterImageProvider.Source); } FillChannelData(channel, destination, scaledChannelSurface, dstRect); } } if (wroteRect != null) { *wroteRect = dstRect; } return(PSError.noErr); }
private unsafe IntPtr CreateReadChannelDesc(int channel, string name, int depth, VRect bounds) { IntPtr addressPtr = Memory.Allocate(Marshal.SizeOf(typeof(ReadChannelDesc)), true); IntPtr namePtr = IntPtr.Zero; try { namePtr = Marshal.StringToHGlobalAnsi(name); channelReadDescPtrs.Add(new ChannelDescPtrs(addressPtr, namePtr)); } catch (Exception) { Memory.Free(addressPtr); if (namePtr != IntPtr.Zero) { Marshal.FreeHGlobal(namePtr); } throw; } ReadChannelDesc *desc = (ReadChannelDesc *)addressPtr.ToPointer(); desc->minVersion = PSConstants.kCurrentMinVersReadChannelDesc; desc->maxVersion = PSConstants.kCurrentMaxVersReadChannelDesc; desc->depth = depth; desc->bounds = bounds; desc->target = channel < PSConstants.ChannelPorts.Alpha; desc->shown = channel < PSConstants.ChannelPorts.SelectionMask; desc->tileOrigin.h = 0; desc->tileOrigin.v = 0; desc->tileSize.h = bounds.right - bounds.left; desc->tileSize.v = bounds.bottom - bounds.top; desc->port = new IntPtr(channel); switch (channel) { case PSConstants.ChannelPorts.Red: desc->channelType = ChannelTypes.Red; break; case PSConstants.ChannelPorts.Green: desc->channelType = ChannelTypes.Green; break; case PSConstants.ChannelPorts.Blue: desc->channelType = ChannelTypes.Blue; break; case PSConstants.ChannelPorts.Alpha: desc->channelType = ChannelTypes.Transparency; break; case PSConstants.ChannelPorts.SelectionMask: desc->channelType = ChannelTypes.SelectionMask; break; } desc->name = namePtr; return(addressPtr); }