protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { int width = sourceData.Width; int height = sourceData.Height; int width2 = destinationData.Width; int height2 = destinationData.Height; int num = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8; int stride = sourceData.Stride; int stride2 = destinationData.Stride; int num2 = stride2 - width2 * num; List <IntPoint> list = new List <IntPoint>(); list.Add(new IntPoint(0, 0)); list.Add(new IntPoint(width2 - 1, 0)); list.Add(new IntPoint(width2 - 1, height2 - 1)); list.Add(new IntPoint(0, height2 - 1)); double[,] array = QuadTransformationCalcs.MapQuadToQuad(list, sourceQuadrilateral); byte *ptr = (byte *)destinationData.ImageData.ToPointer(); byte *ptr2 = (byte *)sourceData.ImageData.ToPointer(); if (!useInterpolation) { for (int i = 0; i < height2; i++) { for (int j = 0; j < width2; j++) { double num3 = array[2, 0] * (double)j + array[2, 1] * (double)i + array[2, 2]; double num4 = (array[0, 0] * (double)j + array[0, 1] * (double)i + array[0, 2]) / num3; double num5 = (array[1, 0] * (double)j + array[1, 1] * (double)i + array[1, 2]) / num3; if (num4 >= 0.0 && num5 >= 0.0 && num4 < (double)width && num5 < (double)height) { byte *ptr3 = ptr2 + (long)(int)num5 * (long)stride + (long)(int)num4 * (long)num; int num6 = 0; while (num6 < num) { *ptr = *ptr3; num6++; ptr++; ptr3++; } } else { ptr += num; } } ptr += num2; } return; } int num7 = width - 1; int num8 = height - 1; for (int k = 0; k < height2; k++) { for (int l = 0; l < width2; l++) { double num9 = array[2, 0] * (double)l + array[2, 1] * (double)k + array[2, 2]; double num10 = (array[0, 0] * (double)l + array[0, 1] * (double)k + array[0, 2]) / num9; double num11 = (array[1, 0] * (double)l + array[1, 1] * (double)k + array[1, 2]) / num9; if (num10 >= 0.0 && num11 >= 0.0 && num10 < (double)width && num11 < (double)height) { int num12 = (int)num10; int num13 = (num12 == num7) ? num12 : (num12 + 1); double num14 = num10 - (double)num12; double num15 = 1.0 - num14; int num16 = (int)num11; int num17 = (num16 == num8) ? num16 : (num16 + 1); double num18 = num11 - (double)num16; double num19 = 1.0 - num18; byte * ptr4; byte * ptr5 = ptr4 = ptr2 + (long)num16 * (long)stride; ptr5 += (long)num12 * (long)num; ptr4 += (long)num13 * (long)num; byte *ptr6; byte *ptr7 = ptr6 = ptr2 + (long)num17 * (long)stride; ptr7 += (long)num12 * (long)num; ptr6 += (long)num13 * (long)num; int num20 = 0; while (num20 < num) { *ptr = (byte)(num19 * (num15 * (double)(int)(*ptr5) + num14 * (double)(int)(*ptr4)) + num18 * (num15 * (double)(int)(*ptr7) + num14 * (double)(int)(*ptr6))); num20++; ptr++; ptr5++; ptr4++; ptr7++; ptr6++; } } else { ptr += num; } } ptr += num2; } }
// Process both images transforming source image into quadrilateral in destination image private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage) { // get source and destination images size var srcWidth = srcImage.Width; var srcHeight = srcImage.Height; var dstWidth = dstImage.Width; var dstHeight = dstImage.Height; var pixelSize = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8; var srcStride = srcImage.Stride; var dstStride = dstImage.Stride; // get bounding rectangle of the quadrilateral IntPoint minXY, maxXY; PointsCloud.GetBoundingRectangle(destinationQuadrilateral, out minXY, out maxXY); // make sure the rectangle is inside of destination image if ((maxXY.X < 0) || (maxXY.Y < 0) || (minXY.X >= dstWidth) || (minXY.Y >= dstHeight)) { return; // nothing to do, since quadrilateral is completely outside } // correct rectangle if required if (minXY.X < 0) { minXY.X = 0; } if (minXY.Y < 0) { minXY.Y = 0; } if (maxXY.X >= dstWidth) { maxXY.X = dstWidth - 1; } if (maxXY.Y >= dstHeight) { maxXY.Y = dstHeight - 1; } var startX = minXY.X; var startY = minXY.Y; var stopX = maxXY.X + 1; var stopY = maxXY.Y + 1; var offset = dstStride - (stopX - startX) * pixelSize; // calculate tranformation matrix var srcRect = new List <IntPoint> { new IntPoint(0, 0), new IntPoint(srcWidth - 1, 0), new IntPoint(srcWidth - 1, srcHeight - 1), new IntPoint(0, srcHeight - 1) }; var matrix = QuadTransformationCalcs.MapQuadToQuad(destinationQuadrilateral, srcRect); // do the job var ptr = (byte *)dstImage.ImageData.ToPointer(); var baseSrc = (byte *)srcImage.ImageData.ToPointer(); // allign pointer to the first pixel to process ptr += (startY * dstStride + startX * pixelSize); if (!useInterpolation) { byte *p; // for each row for (var y = startY; y < stopY; y++) { // for each pixel for (var x = startX; x < stopX; x++) { var factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2]; var srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor; var srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor; if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight)) { // get pointer to the pixel in the source image p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize; // copy pixel's values for (var i = 0; i < pixelSize; i++, ptr++, p++) { *ptr = *p; } } else { // skip the pixel ptr += pixelSize; } } ptr += offset; } } else { var srcWidthM1 = srcWidth - 1; var srcHeightM1 = srcHeight - 1; // coordinates of source points double dx1, dy1, dx2, dy2; int sx1, sy1, sx2, sy2; // temporary pointers byte *p1, p2, p3, p4; // for each row for (var y = startY; y < stopY; y++) { // for each pixel for (var x = startX; x < stopX; x++) { var factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2]; var srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor; var srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor; if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight)) { sx1 = (int)srcX; sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1; dx1 = srcX - sx1; dx2 = 1.0 - dx1; sy1 = (int)srcY; sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1; dy1 = srcY - sy1; dy2 = 1.0 - dy1; // get four points p1 = p2 = baseSrc + sy1 * srcStride; p1 += sx1 * pixelSize; p2 += sx2 * pixelSize; p3 = p4 = baseSrc + sy2 * srcStride; p3 += sx1 * pixelSize; p4 += sx2 * pixelSize; // interpolate using 4 points for (var i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++) { *ptr = (byte)( dy2 * (dx2 * (*p1) + dx1 * (*p2)) + dy1 * (dx2 * (*p3) + dx1 * (*p4))); } } else { // skip the pixel ptr += pixelSize; } } ptr += offset; } } }
private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage) { int width = srcImage.Width; int height = srcImage.Height; int width2 = dstImage.Width; int height2 = dstImage.Height; int num = System.Drawing.Image.GetPixelFormatSize(srcImage.PixelFormat) / 8; int stride = srcImage.Stride; int stride2 = dstImage.Stride; PointsCloud.GetBoundingRectangle(destinationQuadrilateral, out IntPoint minXY, out IntPoint maxXY); if (maxXY.X < 0 || maxXY.Y < 0 || minXY.X >= width2 || minXY.Y >= height2) { return; } if (minXY.X < 0) { minXY.X = 0; } if (minXY.Y < 0) { minXY.Y = 0; } if (maxXY.X >= width2) { maxXY.X = width2 - 1; } if (maxXY.Y >= height2) { maxXY.Y = height2 - 1; } int x = minXY.X; int y = minXY.Y; int num2 = maxXY.X + 1; int num3 = maxXY.Y + 1; int num4 = stride2 - (num2 - x) * num; List <IntPoint> list = new List <IntPoint>(); list.Add(new IntPoint(0, 0)); list.Add(new IntPoint(width - 1, 0)); list.Add(new IntPoint(width - 1, height - 1)); list.Add(new IntPoint(0, height - 1)); double[,] array = QuadTransformationCalcs.MapQuadToQuad(destinationQuadrilateral, list); byte *ptr = (byte *)dstImage.ImageData.ToPointer(); byte *ptr2 = (byte *)srcImage.ImageData.ToPointer(); ptr += y * stride2 + x * num; if (!useInterpolation) { for (int i = y; i < num3; i++) { for (int j = x; j < num2; j++) { double num5 = array[2, 0] * (double)j + array[2, 1] * (double)i + array[2, 2]; double num6 = (array[0, 0] * (double)j + array[0, 1] * (double)i + array[0, 2]) / num5; double num7 = (array[1, 0] * (double)j + array[1, 1] * (double)i + array[1, 2]) / num5; if (num6 >= 0.0 && num7 >= 0.0 && num6 < (double)width && num7 < (double)height) { byte *ptr3 = ptr2 + (long)(int)num7 * (long)stride + (long)(int)num6 * (long)num; int num8 = 0; while (num8 < num) { *ptr = *ptr3; num8++; ptr++; ptr3++; } } else { ptr += num; } } ptr += num4; } return; } int num9 = width - 1; int num10 = height - 1; for (int k = y; k < num3; k++) { for (int l = x; l < num2; l++) { double num11 = array[2, 0] * (double)l + array[2, 1] * (double)k + array[2, 2]; double num12 = (array[0, 0] * (double)l + array[0, 1] * (double)k + array[0, 2]) / num11; double num13 = (array[1, 0] * (double)l + array[1, 1] * (double)k + array[1, 2]) / num11; if (num12 >= 0.0 && num13 >= 0.0 && num12 < (double)width && num13 < (double)height) { int num14 = (int)num12; int num15 = (num14 == num9) ? num14 : (num14 + 1); double num16 = num12 - (double)num14; double num17 = 1.0 - num16; int num18 = (int)num13; int num19 = (num18 == num10) ? num18 : (num18 + 1); double num20 = num13 - (double)num18; double num21 = 1.0 - num20; byte * ptr4; byte * ptr5 = ptr4 = ptr2 + (long)num18 * (long)stride; ptr5 += (long)num14 * (long)num; ptr4 += (long)num15 * (long)num; byte *ptr6; byte *ptr7 = ptr6 = ptr2 + (long)num19 * (long)stride; ptr7 += (long)num14 * (long)num; ptr6 += (long)num15 * (long)num; int num22 = 0; while (num22 < num) { *ptr = (byte)(num21 * (num17 * (double)(int)(*ptr5) + num16 * (double)(int)(*ptr4)) + num20 * (num17 * (double)(int)(*ptr7) + num16 * (double)(int)(*ptr6))); num22++; ptr++; ptr5++; ptr4++; ptr7++; ptr6++; } } else { ptr += num; } } ptr += num4; } }
/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// <param name="destinationData">Destination image data.</param> /// protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { // get source and destination images size int srcWidth = sourceData.Width; int srcHeight = sourceData.Height; int dstWidth = destinationData.Width; int dstHeight = destinationData.Height; int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8; int srcStride = sourceData.Stride; int dstStride = destinationData.Stride; int offset = dstStride - dstWidth * pixelSize; // calculate tranformation matrix List <IntPoint> dstRect = new List <IntPoint>( ); dstRect.Add(new IntPoint(0, 0)); dstRect.Add(new IntPoint(dstWidth - 1, 0)); dstRect.Add(new IntPoint(dstWidth - 1, dstHeight - 1)); dstRect.Add(new IntPoint(0, dstHeight - 1)); // calculate tranformation matrix double[,] matrix = QuadTransformationCalcs.MapQuadToQuad(dstRect, sourceQuadrilateral); // do the job byte *ptr = (byte *)destinationData.ImageData.ToPointer( ); byte *baseSrc = (byte *)sourceData.ImageData.ToPointer( ); if (!useInterpolation) { byte *p; // for each row for (int y = 0; y < dstHeight; y++) { // for each pixel for (int x = 0; x < dstWidth; x++) { double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2]; double srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor; double srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor; if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight)) { // get pointer to the pixel in the source image p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize; // copy pixel's values for (int i = 0; i < pixelSize; i++, ptr++, p++) { *ptr = *p; } } else { ptr += pixelSize; } } ptr += offset; } } else { int srcWidthM1 = srcWidth - 1; int srcHeightM1 = srcHeight - 1; // coordinates of source points double dx1, dy1, dx2, dy2; int sx1, sy1, sx2, sy2; // temporary pointers byte *p1, p2, p3, p4; // for each row for (int y = 0; y < dstHeight; y++) { // for each pixel for (int x = 0; x < dstWidth; x++) { double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2]; double srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor; double srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor; if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight)) { sx1 = (int)srcX; sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1; dx1 = srcX - sx1; dx2 = 1.0 - dx1; sy1 = (int)srcY; sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1; dy1 = srcY - sy1; dy2 = 1.0 - dy1; // get four points p1 = p2 = baseSrc + sy1 * srcStride; p1 += sx1 * pixelSize; p2 += sx2 * pixelSize; p3 = p4 = baseSrc + sy2 * srcStride; p3 += sx1 * pixelSize; p4 += sx2 * pixelSize; // interpolate using 4 points for (int i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++) { *ptr = (byte)( dy2 * (dx2 * (*p1) + dx1 * (*p2)) + dy1 * (dx2 * (*p3) + dx1 * (*p4))); } } else { ptr += pixelSize; } } ptr += offset; } } }
private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage) { IntPoint point; IntPoint point2; int width = srcImage.Width; int height = srcImage.Height; int num3 = dstImage.Width; int num4 = dstImage.Height; int num5 = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8; int stride = srcImage.Stride; int num7 = dstImage.Stride; PointsCloud.GetBoundingRectangle(this.destinationQuadrilateral, ref point, ref point2); if (((point2.X >= 0) && (point2.Y >= 0)) && ((point.X < num3) && (point.Y < num4))) { if (point.X < 0) { point.X = 0; } if (point.Y < 0) { point.Y = 0; } if (point2.X >= num3) { point2.X = num3 - 1; } if (point2.Y >= num4) { point2.Y = num4 - 1; } int x = point.X; int y = point.Y; int num10 = point2.X + 1; int num11 = point2.Y + 1; int num12 = num7 - ((num10 - x) * num5); List <IntPoint> output = new List <IntPoint> { new IntPoint(0, 0), new IntPoint(width - 1, 0), new IntPoint(width - 1, height - 1), new IntPoint(0, height - 1) }; double[,] numArray = QuadTransformationCalcs.MapQuadToQuad(this.destinationQuadrilateral, output); byte *numPtr = (byte *)dstImage.ImageData.ToPointer(); byte *numPtr2 = (byte *)srcImage.ImageData.ToPointer(); numPtr += (y * num7) + (x * num5); if (!this.useInterpolation) { for (int i = y; i < num11; i++) { for (int j = x; j < num10; j++) { double num15 = ((numArray[2, 0] * j) + (numArray[2, 1] * i)) + numArray[2, 2]; double num16 = (((numArray[0, 0] * j) + (numArray[0, 1] * i)) + numArray[0, 2]) / num15; double num17 = (((numArray[1, 0] * j) + (numArray[1, 1] * i)) + numArray[1, 2]) / num15; if (((num16 >= 0.0) && (num17 >= 0.0)) && ((num16 < width) && (num17 < height))) { byte *numPtr3 = (numPtr2 + (((int)num17) * stride)) + (((int)num16) * num5); int num18 = 0; while (num18 < num5) { numPtr[0] = numPtr3[0]; num18++; numPtr++; numPtr3++; } } else { numPtr += num5; } } numPtr += num12; } } else { int num19 = width - 1; int num20 = height - 1; for (int k = y; k < num11; k++) { for (int m = x; m < num10; m++) { double num31 = ((numArray[2, 0] * m) + (numArray[2, 1] * k)) + numArray[2, 2]; double num32 = (((numArray[0, 0] * m) + (numArray[0, 1] * k)) + numArray[0, 2]) / num31; double num33 = (((numArray[1, 0] * m) + (numArray[1, 1] * k)) + numArray[1, 2]) / num31; if (((num32 >= 0.0) && (num33 >= 0.0)) && ((num32 < width) && (num33 < height))) { byte * numPtr5; byte * numPtr7; int num25 = (int)num32; int num27 = (num25 == num19) ? num25 : (num25 + 1); double num21 = num32 - num25; double num23 = 1.0 - num21; int num26 = (int)num33; int num28 = (num26 == num20) ? num26 : (num26 + 1); double num22 = num33 - num26; double num24 = 1.0 - num22; byte * numPtr4 = numPtr5 = numPtr2 + (num26 * stride); numPtr4 += num25 * num5; numPtr5 += num27 * num5; byte *numPtr6 = numPtr7 = numPtr2 + (num28 * stride); numPtr6 += num25 * num5; numPtr7 += num27 * num5; int num34 = 0; while (num34 < num5) { numPtr[0] = (byte)((num24 * ((num23 * numPtr4[0]) + (num21 * numPtr5[0]))) + (num22 * ((num23 * numPtr6[0]) + (num21 * numPtr7[0])))); num34++; numPtr++; numPtr4++; numPtr5++; numPtr6++; numPtr7++; } } else { numPtr += num5; } } numPtr += num12; } } } }