csputils.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright (C) 2024 Niklas Haas
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #ifndef SWSCALE_CSPUTILS_H
  21. #define SWSCALE_CSPUTILS_H
  22. #include <stdint.h>
  23. #include <stdbool.h>
  24. #include <math.h>
  25. #include "libavutil/attributes.h"
  26. #include "libavutil/common.h"
  27. #include "libavutil/csp.h"
  28. #include "libavutil/pixfmt.h"
  29. /* Shared constants and helpers for colorspace mapping */
  30. #define fmixf(a, b, x) ((b) * (x) + (a) * (1 - (x)))
  31. static inline float smoothstepf(float edge0, float edge1, float x)
  32. {
  33. if (edge0 == edge1)
  34. return x >= edge0;
  35. x = (x - edge0) / (edge1 - edge0);
  36. x = av_clipf(x, 0.0f, 1.0f);
  37. return x * x * (3.0f - 2.0f * x);
  38. }
  39. /* 3x3 matrix math */
  40. typedef struct SwsMatrix3x3 {
  41. float m[3][3];
  42. } SwsMatrix3x3;
  43. void ff_sws_matrix3x3_mul(SwsMatrix3x3 *a, const SwsMatrix3x3 *b);
  44. void ff_sws_matrix3x3_rmul(const SwsMatrix3x3 *a, SwsMatrix3x3 *b);
  45. void ff_sws_matrix3x3_invert(SwsMatrix3x3 *mat);
  46. void ff_sws_matrix3x3_apply(const SwsMatrix3x3 *mat, float vec[3]);
  47. SwsMatrix3x3 ff_sws_ipt_rgb2lms(const AVColorPrimariesDesc *prim);
  48. SwsMatrix3x3 ff_sws_ipt_lms2rgb(const AVColorPrimariesDesc *prim);
  49. /* Converts to/from XYZ (relative to the given white point, no adaptation) */
  50. SwsMatrix3x3 ff_sws_rgb2xyz(const AVColorPrimariesDesc *prim);
  51. SwsMatrix3x3 ff_sws_xyz2rgb(const AVColorPrimariesDesc *prim);
  52. /* Returns an RGB -> RGB adaptation matrix */
  53. SwsMatrix3x3 ff_sws_get_adaptation(const AVPrimaryCoefficients *prim,
  54. AVWhitepointCoefficients from,
  55. AVWhitepointCoefficients to);
  56. /* Integer math definitions / helpers */
  57. typedef struct v3u8_t {
  58. uint8_t x, y, z;
  59. } v3u8_t;
  60. typedef struct v2u16_t {
  61. uint16_t x, y;
  62. } v2u16_t;
  63. typedef struct v3u16_t {
  64. uint16_t x, y, z;
  65. } v3u16_t;
  66. /* Fast perceptual quantizer */
  67. static const float PQ_M1 = 2610./4096 * 1./4,
  68. PQ_M2 = 2523./4096 * 128,
  69. PQ_C1 = 3424./4096,
  70. PQ_C2 = 2413./4096 * 32,
  71. PQ_C3 = 2392./4096 * 32;
  72. enum { PQ_LUT_SIZE = 1024 };
  73. extern const float ff_pq_eotf_lut[PQ_LUT_SIZE+1];
  74. static inline float pq_eotf(float x)
  75. {
  76. float idxf = av_clipf(x, 0.0f, 1.0f) * (PQ_LUT_SIZE - 1);
  77. int ipart = floorf(idxf);
  78. float fpart = idxf - ipart;
  79. return fmixf(ff_pq_eotf_lut[ipart], ff_pq_eotf_lut[ipart + 1], fpart);
  80. }
  81. static inline float pq_oetf(float x)
  82. {
  83. x = powf(fmaxf(x * 1e-4f, 0.0f), PQ_M1);
  84. x = (PQ_C1 + PQ_C2 * x) / (1.0f + PQ_C3 * x);
  85. return powf(x, PQ_M2);
  86. }
  87. /* Misc colorspace math / helpers */
  88. /**
  89. * Returns true if 'b' is entirely contained in 'a'. Useful for figuring out if
  90. * colorimetric clipping will occur or not.
  91. */
  92. bool ff_prim_superset(const AVPrimaryCoefficients *a, const AVPrimaryCoefficients *b);
  93. #endif /* SWSCALE_CSPUTILS_H */