Message ID | 20241107114819.57599-2-dan.scally@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi Dan On Thu, Nov 07, 2024 at 11:48:09AM +0000, Daniel Scally wrote: > Add functions to convert a double to or from an unsigned Q(m,n) > format. As the format is unsigned this most resembles the UQ variant > of the TI implementation detailed on Wikipedia: > > https://en.wikipedia.org/wiki/Q_(number_format) > > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> > --- > Changes in v3: > > - New patch > > src/ipa/libipa/helpers.cpp | 29 +++++++++++++++++++++++++++++ > src/ipa/libipa/helpers.h | 2 ++ > 2 files changed, 31 insertions(+) > > diff --git a/src/ipa/libipa/helpers.cpp b/src/ipa/libipa/helpers.cpp > index 6c038895..908c6e93 100644 > --- a/src/ipa/libipa/helpers.cpp > +++ b/src/ipa/libipa/helpers.cpp > @@ -72,6 +72,35 @@ uint32_t estimateCCT(double red, double green, double blue) > return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; > } > > +/** > + * \brief Convert double to Q(m.n) format > + * \param[in] value The value to convert I would mention you expect only positive values > + * \param[in] m The number of bits used to represent the integer part > + * \param[in] n The number of bits used to represent the fraction part > + * > + * This function converts a double into an unsigned fractional Q format, > + * clamping at the largest possible value given m and n. As these formats are > + * unsigned the m figure does not include a sign bit. > + */ > +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n) double can be negative, and if a negative is provided it gets automatically converted to 0. Should this be catch ? If this function does not support negative input values, I would rather catch this earlier even by using FATAL as this is programming "error" and shouldn't be triggered by user input ? > +{ > + double maxVal = (std::pow(2, m + n) - 1) / std::pow(2, n); > + > + return std::clamp(value, 0.0, maxVal) * std::pow(2, n); > +} > + > +/** > + * \brief Convert Q(m.n) formatted number to double > + * \param[in] value The value to convert > + * \param[in] n The number of bits used to represent the fraction part > + * > + * This function converts an unsigned Q formatted value into a double. > + */ > +double fromUnsignedQFormat(unsigned int value, unsigned int n) > +{ > + return value / std::pow(2, n); > +} > + > } /* namespace ipa */ > > } /* namespace libcamera */ > diff --git a/src/ipa/libipa/helpers.h b/src/ipa/libipa/helpers.h > index 51c74a36..1f26e768 100644 > --- a/src/ipa/libipa/helpers.h > +++ b/src/ipa/libipa/helpers.h > @@ -15,6 +15,8 @@ namespace ipa { > > double rec601LuminanceFromRGB(unsigned int r, unsigned int g, unsigned int b); > uint32_t estimateCCT(double red, double green, double blue); > +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n); > +double fromUnsignedQFormat(unsigned int value, unsigned int n); > > } /* namespace ipa */ > > -- > 2.30.2 >
Hi Dan, Thank you for the patch. On Thu, Nov 07, 2024 at 11:48:09AM +0000, Daniel Scally wrote: > Add functions to convert a double to or from an unsigned Q(m,n) > format. As the format is unsigned this most resembles the UQ variant > of the TI implementation detailed on Wikipedia: > > https://en.wikipedia.org/wiki/Q_(number_format) Time to move src/ipa/rkisp1/utils.{h,cpp} to libipa ? I would then call it math.h, fixedpoint.h or something similar. > Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> > --- > Changes in v3: > > - New patch > > src/ipa/libipa/helpers.cpp | 29 +++++++++++++++++++++++++++++ > src/ipa/libipa/helpers.h | 2 ++ > 2 files changed, 31 insertions(+) > > diff --git a/src/ipa/libipa/helpers.cpp b/src/ipa/libipa/helpers.cpp > index 6c038895..908c6e93 100644 > --- a/src/ipa/libipa/helpers.cpp > +++ b/src/ipa/libipa/helpers.cpp > @@ -72,6 +72,35 @@ uint32_t estimateCCT(double red, double green, double blue) > return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; > } > > +/** > + * \brief Convert double to Q(m.n) format > + * \param[in] value The value to convert > + * \param[in] m The number of bits used to represent the integer part > + * \param[in] n The number of bits used to represent the fraction part > + * > + * This function converts a double into an unsigned fractional Q format, > + * clamping at the largest possible value given m and n. As these formats are > + * unsigned the m figure does not include a sign bit. > + */ > +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n) > +{ > + double maxVal = (std::pow(2, m + n) - 1) / std::pow(2, n); > + > + return std::clamp(value, 0.0, maxVal) * std::pow(2, n); > +} > + > +/** > + * \brief Convert Q(m.n) formatted number to double > + * \param[in] value The value to convert > + * \param[in] n The number of bits used to represent the fraction part > + * > + * This function converts an unsigned Q formatted value into a double. > + */ > +double fromUnsignedQFormat(unsigned int value, unsigned int n) > +{ > + return value / std::pow(2, n); > +} > + > } /* namespace ipa */ > > } /* namespace libcamera */ > diff --git a/src/ipa/libipa/helpers.h b/src/ipa/libipa/helpers.h > index 51c74a36..1f26e768 100644 > --- a/src/ipa/libipa/helpers.h > +++ b/src/ipa/libipa/helpers.h > @@ -15,6 +15,8 @@ namespace ipa { > > double rec601LuminanceFromRGB(unsigned int r, unsigned int g, unsigned int b); > uint32_t estimateCCT(double red, double green, double blue); > +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n); > +double fromUnsignedQFormat(unsigned int value, unsigned int n); > > } /* namespace ipa */ >
diff --git a/src/ipa/libipa/helpers.cpp b/src/ipa/libipa/helpers.cpp index 6c038895..908c6e93 100644 --- a/src/ipa/libipa/helpers.cpp +++ b/src/ipa/libipa/helpers.cpp @@ -72,6 +72,35 @@ uint32_t estimateCCT(double red, double green, double blue) return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; } +/** + * \brief Convert double to Q(m.n) format + * \param[in] value The value to convert + * \param[in] m The number of bits used to represent the integer part + * \param[in] n The number of bits used to represent the fraction part + * + * This function converts a double into an unsigned fractional Q format, + * clamping at the largest possible value given m and n. As these formats are + * unsigned the m figure does not include a sign bit. + */ +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n) +{ + double maxVal = (std::pow(2, m + n) - 1) / std::pow(2, n); + + return std::clamp(value, 0.0, maxVal) * std::pow(2, n); +} + +/** + * \brief Convert Q(m.n) formatted number to double + * \param[in] value The value to convert + * \param[in] n The number of bits used to represent the fraction part + * + * This function converts an unsigned Q formatted value into a double. + */ +double fromUnsignedQFormat(unsigned int value, unsigned int n) +{ + return value / std::pow(2, n); +} + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/helpers.h b/src/ipa/libipa/helpers.h index 51c74a36..1f26e768 100644 --- a/src/ipa/libipa/helpers.h +++ b/src/ipa/libipa/helpers.h @@ -15,6 +15,8 @@ namespace ipa { double rec601LuminanceFromRGB(unsigned int r, unsigned int g, unsigned int b); uint32_t estimateCCT(double red, double green, double blue); +unsigned int toUnsignedQFormat(double value, unsigned int m, unsigned int n); +double fromUnsignedQFormat(unsigned int value, unsigned int n); } /* namespace ipa */
Add functions to convert a double to or from an unsigned Q(m,n) format. As the format is unsigned this most resembles the UQ variant of the TI implementation detailed on Wikipedia: https://en.wikipedia.org/wiki/Q_(number_format) Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> --- Changes in v3: - New patch src/ipa/libipa/helpers.cpp | 29 +++++++++++++++++++++++++++++ src/ipa/libipa/helpers.h | 2 ++ 2 files changed, 31 insertions(+)