UnaryPixelOp.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using System;
  2. using System.Drawing;
  3. namespace PaintDotNet
  4. {
  5. /// <summary>
  6. /// Defines a way to operate on a pixel, or a region of pixels, in a unary fashion.
  7. /// That is, it is a simple function F that takes one parameter and returns a
  8. /// result of the form: d = F(c)
  9. /// </summary>
  10. [Serializable]
  11. public unsafe abstract class UnaryPixelOp
  12. : PixelOp
  13. {
  14. public abstract ColorBgra Apply(ColorBgra color);
  15. public unsafe override void Apply(ColorBgra* dst, ColorBgra* src, int length)
  16. {
  17. unsafe
  18. {
  19. while (length > 0)
  20. {
  21. *dst = Apply(*src);
  22. ++dst;
  23. ++src;
  24. --length;
  25. }
  26. }
  27. }
  28. public unsafe virtual void Apply(ColorBgra* ptr, int length)
  29. {
  30. unsafe
  31. {
  32. while (length > 0)
  33. {
  34. *ptr = Apply(*ptr);
  35. ++ptr;
  36. --length;
  37. }
  38. }
  39. }
  40. private unsafe void ApplyRectangle(Surface surface, Rectangle rect)
  41. {
  42. for (int y = rect.Top; y < rect.Bottom; ++y)
  43. {
  44. ColorBgra* ptr = surface.GetPointAddress(rect.Left, y);
  45. Apply(ptr, rect.Width);
  46. }
  47. }
  48. public void Apply(Surface surface, Rectangle[] roi, int startIndex, int length)
  49. {
  50. Rectangle regionBounds = Utility.GetRegionBounds(roi, startIndex, length);
  51. if (regionBounds != Rectangle.Intersect(surface.Bounds, regionBounds))
  52. {
  53. throw new ArgumentOutOfRangeException("roi", "Region is out of bounds");
  54. }
  55. unsafe
  56. {
  57. for (int x = startIndex; x < startIndex + length; ++x)
  58. {
  59. ApplyRectangle(surface, roi[x]);
  60. }
  61. }
  62. }
  63. public void Apply(Surface surface, Rectangle[] roi)
  64. {
  65. Apply(surface, roi, 0, roi.Length);
  66. }
  67. public void Apply(Surface surface, RectangleF[] roiF, int startIndex, int length)
  68. {
  69. Rectangle regionBounds = Rectangle.Truncate(Utility.GetRegionBounds(roiF, startIndex, length));
  70. if (regionBounds != Rectangle.Intersect(surface.Bounds, regionBounds))
  71. {
  72. throw new ArgumentOutOfRangeException("roiF", "Region is out of bounds");
  73. }
  74. unsafe
  75. {
  76. for (int x = startIndex; x < startIndex + length; ++x)
  77. {
  78. ApplyRectangle(surface, Rectangle.Truncate(roiF[x]));
  79. }
  80. }
  81. }
  82. public unsafe void Apply(Surface surface, Rectangle roi)
  83. {
  84. ApplyRectangle(surface, roi);
  85. }
  86. public override void Apply(Surface dst, Point dstOffset, Surface src, Point srcOffset, int scanLength)
  87. {
  88. Apply(dst.GetPointAddress(dstOffset), src.GetPointAddress(srcOffset), scanLength);
  89. }
  90. public UnaryPixelOp()
  91. {
  92. }
  93. }
  94. }