Exemplo n.º 1
0
        private void TransformPerPixelBase(ImageBuffer target, IList <Point> path = null, Int32 parallelTaskCount = 4, params Delegate[] passes)
        {
            // checks parameters
            Guard.CheckNull(target, "target");
            Guard.CheckNull(passes, "passes");

            // creates internal quantizer if needed
            UpdatePalette();
            target.UpdatePalette();

            // checks the dimensions
            if (Width != target.Width || Height != target.Height)
            {
                const String message = "Both images have to have the same dimensions.";
                throw new ArgumentOutOfRangeException(message);
            }

            // determines mode
            Boolean isAdvanced = passes.Length > 0 && passes[0] is TransformPixelAdvancedFunction;

            // creates default path, if none is available
            if (path == null)
            {
                path = StandardPathProvider.CreatePath(Width, Height);
            }

            // process the image in a parallel manner
            Action <LineTask> transformPerPixel = lineTask =>
            {
                // creates individual pixel structures per task
                Pixel    sourcePixel = CreatePixel();
                Pixel    targetPixel = target.CreatePixel();
                Delegate pass        = passes[lineTask.PassIndex];

                // enumerates the pixels row by row
                for (Int32 pathOffset = lineTask.StartOffset; pathOffset < lineTask.EndOffset; pathOffset++)
                {
                    Point   point = path[pathOffset];
                    Boolean allowWrite;

                    // enumerates the pixel, and returns the control to the outside
                    sourcePixel.Update(point.X, point.Y);
                    targetPixel.Update(point.X, point.Y);

                    // when read is allowed, retrieves current value (in bytes)
                    if (CanRead)
                    {
                        ReadPixel(sourcePixel);
                    }
                    if (target.CanRead)
                    {
                        target.ReadPixel(targetPixel);
                    }

                    // process the pixel by custom user operation
                    if (isAdvanced)
                    {
                        TransformPixelAdvancedFunction transformAdvancedFunction = (TransformPixelAdvancedFunction)pass;
                        allowWrite = transformAdvancedFunction(lineTask.PassIndex, sourcePixel, targetPixel, this, target);
                    }
                    else // use simplified version with pixel parameters only
                    {
                        TransformPixelFunction transformFunction = (TransformPixelFunction)pass;
                        allowWrite = transformFunction(lineTask.PassIndex, sourcePixel, targetPixel);
                    }

                    // when write is allowed, copies the value back to the row buffer
                    if (target.CanWrite && allowWrite)
                    {
                        target.WritePixel(targetPixel);
                    }
                }
            };

            // transforms image per pixel
            for (Int32 passIndex = 0; passIndex < passes.Length; passIndex++)
            {
                ProcessInParallel(passIndex, transformPerPixel, path, parallelTaskCount);
            }
        }
Exemplo n.º 2
0
        private void ProcessPerPixelBase(IList <Point> path = null, Int32 parallelTaskCount = 4, params Delegate[] passes)
        {
            // checks parameters
            Guard.CheckNull(passes, "passes");

            // determines mode
            Boolean isAdvanced = passes.Length > 0 && passes[0] is ProcessPixelAdvancedFunction;

            // creates default path, if none is available
            if (path == null)
            {
                path = StandardPathProvider.CreatePath(Width, Height);
            }

            // prepares the per pixel task
            Action <LineTask> processPerPixel = lineTask =>
            {
                // initializes variables per task
                Pixel    pixel = CreatePixel();
                Delegate pass  = passes[lineTask.PassIndex];

                for (Int32 pathOffset = lineTask.StartOffset; pathOffset < lineTask.EndOffset; pathOffset++)
                {
                    Point   point = path[pathOffset];
                    Boolean allowWrite;

                    // enumerates the pixel, and returns the control to the outside
                    pixel.Update(point.X, point.Y);

                    // when read is allowed, retrieves current value (in bytes)
                    if (CanRead)
                    {
                        ReadPixel(pixel);
                    }

                    // process the pixel by custom user operation
                    if (isAdvanced)
                    {
                        ProcessPixelAdvancedFunction processAdvancedFunction = (ProcessPixelAdvancedFunction)pass;
                        allowWrite = processAdvancedFunction(lineTask.PassIndex, pixel, this);
                    }
                    else // use simplified version with pixel parameter only
                    {
                        ProcessPixelFunction processFunction = (ProcessPixelFunction)pass;
                        allowWrite = processFunction(lineTask.PassIndex, pixel);
                    }

                    // when write is allowed, copies the value back to the row buffer
                    if (CanWrite && allowWrite)
                    {
                        WritePixel(pixel);
                    }
                }
            };

            // processes image per pixel
            for (Int32 passIndex = 0; passIndex < passes.Length; passIndex++)
            {
                ProcessInParallel(passIndex, processPerPixel, path, parallelTaskCount);
            }
        }