interpolation.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #pragma once
  2. namespace nall {
  3. inline auto image::isplit(uint64_t* c, uint64_t color) -> void {
  4. c[0] = (color & _alpha.mask()) >> _alpha.shift();
  5. c[1] = (color & _red.mask() ) >> _red.shift();
  6. c[2] = (color & _green.mask()) >> _green.shift();
  7. c[3] = (color & _blue.mask() ) >> _blue.shift();
  8. }
  9. inline auto image::imerge(const uint64_t* c) -> uint64_t {
  10. return c[0] << _alpha.shift() | c[1] << _red.shift() | c[2] << _green.shift() | c[3] << _blue.shift();
  11. }
  12. inline auto image::interpolate1f(uint64_t a, uint64_t b, double x) -> uint64_t {
  13. return a * (1.0 - x) + b * x;
  14. }
  15. inline auto image::interpolate1f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y) -> uint64_t {
  16. return a * (1.0 - x) * (1.0 - y) + b * x * (1.0 - y) + c * (1.0 - x) * y + d * x * y;
  17. }
  18. inline auto image::interpolate1i(int64_t a, int64_t b, uint32_t x) -> uint64_t {
  19. return a + (((b - a) * x) >> 32); //a + (b - a) * x
  20. }
  21. inline auto image::interpolate1i(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y) -> uint64_t {
  22. a = a + (((b - a) * x) >> 32); //a + (b - a) * x
  23. c = c + (((d - c) * x) >> 32); //c + (d - c) * x
  24. return a + (((c - a) * y) >> 32); //a + (c - a) * y
  25. }
  26. inline auto image::interpolate4f(uint64_t a, uint64_t b, double x) -> uint64_t {
  27. uint64_t o[4], pa[4], pb[4];
  28. isplit(pa, a), isplit(pb, b);
  29. for(uint n = 0; n < 4; n++) o[n] = interpolate1f(pa[n], pb[n], x);
  30. return imerge(o);
  31. }
  32. inline auto image::interpolate4f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y) -> uint64_t {
  33. uint64_t o[4], pa[4], pb[4], pc[4], pd[4];
  34. isplit(pa, a), isplit(pb, b), isplit(pc, c), isplit(pd, d);
  35. for(uint n = 0; n < 4; n++) o[n] = interpolate1f(pa[n], pb[n], pc[n], pd[n], x, y);
  36. return imerge(o);
  37. }
  38. inline auto image::interpolate4i(uint64_t a, uint64_t b, uint32_t x) -> uint64_t {
  39. uint64_t o[4], pa[4], pb[4];
  40. isplit(pa, a), isplit(pb, b);
  41. for(uint n = 0; n < 4; n++) o[n] = interpolate1i(pa[n], pb[n], x);
  42. return imerge(o);
  43. }
  44. inline auto image::interpolate4i(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint32_t x, uint32_t y) -> uint64_t {
  45. uint64_t o[4], pa[4], pb[4], pc[4], pd[4];
  46. isplit(pa, a), isplit(pb, b), isplit(pc, c), isplit(pd, d);
  47. for(uint n = 0; n < 4; n++) o[n] = interpolate1i(pa[n], pb[n], pc[n], pd[n], x, y);
  48. return imerge(o);
  49. }
  50. }