ColorBounds.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.CompilerServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using ComputeSharp;
  8. using SkiaSharp;
  9. namespace ChunkyImageLib.DataHolders;
  10. public struct ColorBounds
  11. {
  12. public float LowerR { get; set; }
  13. public float LowerG { get; set; }
  14. public float LowerB { get; set; }
  15. public float LowerA { get; set; }
  16. public float UpperR { get; set; }
  17. public float UpperG { get; set; }
  18. public float UpperB { get; set; }
  19. public float UpperA { get; set; }
  20. public ColorBounds(SKColor color)
  21. {
  22. static (float lower, float upper) FindInclusiveBoundaryPremul(byte channel, float alpha)
  23. {
  24. float subHalf = channel > 0 ? channel - .5f : channel;
  25. float addHalf = channel < 255 ? channel + .5f : channel;
  26. return (subHalf * alpha / 255f, addHalf * alpha / 255f);
  27. }
  28. static (float lower, float upper) FindInclusiveBoundary(byte channel)
  29. {
  30. float subHalf = channel > 0 ? channel - .5f : channel;
  31. float addHalf = channel < 255 ? channel + .5f : channel;
  32. return (subHalf / 255f, addHalf / 255f);
  33. }
  34. float a = color.Alpha / 255f;
  35. (LowerR, UpperR) = FindInclusiveBoundaryPremul(color.Red, a);
  36. (LowerG, UpperG) = FindInclusiveBoundaryPremul(color.Green, a);
  37. (LowerB, UpperB) = FindInclusiveBoundaryPremul(color.Blue, a);
  38. (LowerA, UpperA) = FindInclusiveBoundary(color.Alpha);
  39. }
  40. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  41. public unsafe bool IsWithinBounds(Half* pixel)
  42. {
  43. float r = (float)pixel[0];
  44. float g = (float)pixel[1];
  45. float b = (float)pixel[2];
  46. float a = (float)pixel[3];
  47. if (r < LowerR || r > UpperR)
  48. return false;
  49. if (g < LowerG || g > UpperG)
  50. return false;
  51. if (b < LowerB || b > UpperB)
  52. return false;
  53. if (a < LowerA || a > UpperA)
  54. return false;
  55. return true;
  56. }
  57. [ShaderMethod]
  58. public readonly bool IsWithinBounds(float4 color)
  59. {
  60. float r = color.R;
  61. float g = color.G;
  62. float b = color.B;
  63. float a = color.A;
  64. if (r < LowerR || r > UpperR)
  65. return false;
  66. if (g < LowerG || g > UpperG)
  67. return false;
  68. if (b < LowerB || b > UpperB)
  69. return false;
  70. return !(a < LowerA) && !(a > UpperA);
  71. }
  72. }