19 using System.Threading.Tasks;
47 RasterImage mask = this.GetCachedRasterisation(scale);
49 IntPtr tbrData = System.Runtime.InteropServices.Marshal.AllocHGlobal(image.
Width * image.
Height * 4);
50 GC.AddMemoryPressure(image.
Width * image.
Height * 4);
52 int width = image.
Width;
55 int pixelSizeInput = image.
HasAlpha ? 4 : 3;
56 int strideInput = image.
Width * pixelSizeInput;
58 int pixelSizeOutput = 4;
59 int strideOutput = image.
Width * pixelSizeOutput;
61 int pixelSizeMask = 4;
62 int strideMask = mask.
Width * pixelSizeMask;
64 int maskWidth = mask.
Width;
65 int maskHeight = mask.
Height;
67 int threads = Math.Min(8, Environment.ProcessorCount);
73 byte* output = (
byte*)tbrData;
81 for (
int x = 0; x < width; x++)
83 int maskX = (int)Math.Round((bounds.
Location.
X + (x + 0.5) * bounds.
Size.
Width / width - CachedBounds.Location.X) / CachedBounds.Size.Width * maskWidth);
84 int maskY = (int)Math.Round((bounds.
Location.
Y + (y + 0.5) * bounds.
Size.
Height / height - CachedBounds.Location.Y) / CachedBounds.Size.Height * maskHeight);
88 if (maskX >= 0 && maskX < maskWidth && maskY >= 0 && maskY < maskHeight)
90 weight = (maskBytes[maskY * strideMask + maskX * pixelSizeMask] * 0.2126 + maskBytes[maskY * strideMask + maskX * pixelSizeMask + 1] * 0.7152 + maskBytes[maskY * strideMask + maskX * pixelSizeMask + 2] * 0.0722) / 255.0;
94 weight *= maskBytes[maskY * strideMask + maskX * pixelSizeMask + 3] / 255.0;
100 output[y * strideOutput + x * 4] = input[y * strideInput + x * 4];
101 output[y * strideOutput + x * 4 + 1] = input[y * strideInput + x * 4 + 1];
102 output[y * strideOutput + x * 4 + 2] = input[y * strideInput + x * 4 + 2];
103 output[y * strideOutput + x * 4 + 3] = (byte)Math.Round(input[y * strideInput + x * 4 + 3] * weight);
107 output[y * strideOutput + x * 4] = 0;
108 output[y * strideOutput + x * 4 + 1] = 0;
109 output[y * strideOutput + x * 4 + 2] = 0;
110 output[y * strideOutput + x * 4 + 3] = 0;
119 for (
int x = 0; x < width; x++)
121 int maskX = (int)Math.Round((bounds.
Location.
X + (x + 0.5) * bounds.
Size.
Width / width - CachedBounds.Location.X) / CachedBounds.Size.Width * maskWidth);
122 int maskY = (int)Math.Round((bounds.
Location.
Y + (y + 0.5) * bounds.
Size.
Height / height - CachedBounds.Location.Y) / CachedBounds.Size.Height * maskHeight);
126 if (maskX >= 0 && maskX < maskWidth && maskY >= 0 && maskY < maskHeight)
128 weight = (maskBytes[maskY * strideMask + maskX * pixelSizeMask] * 0.2126 + maskBytes[maskY * strideMask + maskX * pixelSizeMask + 1] * 0.7152 + maskBytes[maskY * strideMask + maskX * pixelSizeMask + 2] * 0.0722);
132 weight *= maskBytes[maskY * strideMask + maskX * pixelSizeMask + 3] / 255.0;
138 output[y * strideOutput + x * 4] = input[y * strideInput + x * 3];
139 output[y * strideOutput + x * 4 + 1] = input[y * strideInput + x * 3 + 1];
140 output[y * strideOutput + x * 4 + 2] = input[y * strideInput + x * 3 + 2];
141 output[y * strideOutput + x * 4 + 3] = (byte)Math.Round(weight);
145 output[y * strideOutput + x * 4] = 0;
146 output[y * strideOutput + x * 4 + 1] = 0;
147 output[y * strideOutput + x * 4 + 2] = 0;
148 output[y * strideOutput + x * 4 + 3] = 0;
156 for (
int y = 0; y < height; y++)
163 ParallelOptions options =
new ParallelOptions() { MaxDegreeOfParallelism = threads };
165 Parallel.For(0, height, options, yLoop);