in Sources/Imaging/Microsoft.Psi.Imaging/ImageExtensions.cs [2254:2349]
public static void AbsDiff(this Image imageA, Image imageB, Image destImage)
{
if (imageA.PixelFormat != destImage.PixelFormat || imageB.PixelFormat != destImage.PixelFormat)
{
throw new ArgumentOutOfRangeException("destImage.PixelFormat", "destination image pixel format doesn't match source image pixel format");
}
if (imageA.Width != imageB.Width || imageA.Height != imageB.Height || imageA.PixelFormat != imageB.PixelFormat)
{
throw new ArgumentException("Images sizes/types don't match");
}
unsafe
{
int bytesPerPixel = imageA.PixelFormat.GetBytesPerPixel();
byte* srcRowA = (byte*)imageA.ImageData.ToPointer();
byte* srcRowB = (byte*)imageB.ImageData.ToPointer();
byte* dstRow = (byte*)destImage.ImageData.ToPointer();
for (int i = 0; i < imageA.Height; i++)
{
byte* srcColA = srcRowA;
byte* srcColB = srcRowB;
byte* dstCol = dstRow;
int delta0, delta1, delta2, delta3;
for (int j = 0; j < imageA.Width; j++)
{
switch (imageA.PixelFormat)
{
case PixelFormat.BGRA_32bpp:
delta0 = srcColA[0] - srcColB[0];
delta1 = srcColA[1] - srcColB[1];
delta2 = srcColA[2] - srcColB[2];
delta3 = srcColA[3] - srcColB[3];
dstCol[0] = (byte)((delta0 < 0) ? -delta0 : delta0);
dstCol[1] = (byte)((delta1 < 0) ? -delta1 : delta1);
dstCol[2] = (byte)((delta2 < 0) ? -delta2 : delta2);
dstCol[3] = (byte)((delta3 < 0) ? -delta3 : delta3);
break;
case PixelFormat.BGRX_32bpp:
delta0 = srcColA[0] - srcColB[0];
delta1 = srcColA[1] - srcColB[1];
delta2 = srcColA[2] - srcColB[2];
dstCol[0] = (byte)((delta0 < 0) ? -delta0 : delta0);
dstCol[1] = (byte)((delta1 < 0) ? -delta1 : delta1);
dstCol[2] = (byte)((delta2 < 0) ? -delta2 : delta2);
dstCol[3] = 255;
break;
case PixelFormat.BGR_24bpp:
case PixelFormat.RGB_24bpp:
delta0 = srcColA[0] - srcColB[0];
delta1 = srcColA[1] - srcColB[1];
delta2 = srcColA[2] - srcColB[2];
dstCol[0] = (byte)((delta0 < 0) ? -delta0 : delta0);
dstCol[1] = (byte)((delta1 < 0) ? -delta1 : delta1);
dstCol[2] = (byte)((delta2 < 0) ? -delta2 : delta2);
break;
case PixelFormat.Gray_16bpp:
delta0 = ((ushort*)srcColA)[0] - ((ushort*)srcColB)[0];
((ushort*)dstCol)[0] = (ushort)((delta0 < 0) ? -delta0 : delta0);
break;
case PixelFormat.Gray_8bpp:
delta0 = srcColA[0] - srcColB[0];
dstCol[0] = (byte)((delta0 < 0) ? -delta0 : delta0);
break;
case PixelFormat.RGBA_64bpp:
delta0 = (ushort)(((ushort*)srcColA)[0] - ((ushort*)srcColB)[0]);
delta1 = (ushort)(((ushort*)srcColA)[1] - ((ushort*)srcColB)[1]);
delta2 = (ushort)(((ushort*)srcColA)[2] - ((ushort*)srcColB)[2]);
delta3 = (ushort)(((ushort*)srcColA)[3] - ((ushort*)srcColB)[3]);
((ushort*)dstCol)[0] = (ushort)((delta0 < 0) ? -delta0 : delta0);
((ushort*)dstCol)[1] = (ushort)((delta1 < 0) ? -delta1 : delta1);
((ushort*)dstCol)[2] = (ushort)((delta2 < 0) ? -delta2 : delta2);
((ushort*)dstCol)[3] = (ushort)((delta3 < 0) ? -delta3 : delta3);
break;
case PixelFormat.Undefined:
default:
throw new ArgumentException(Image.ExceptionDescriptionUnexpectedPixelFormat);
}
srcColA += bytesPerPixel;
srcColB += bytesPerPixel;
dstCol += bytesPerPixel;
}
srcRowA += imageA.Stride;
srcRowB += imageB.Stride;
dstRow += destImage.Stride;
}
}
}