Files
external_libcamera/test/ipa/libipa/quantized.cpp
Barnabás Pőcze 6ce7132b1b ipa: libipa: quantized: Enable constexpr operation
There is nothing inherently non-constexpr in the `Quantized` type. Whether
it can work in `constexpr` contexts depends on the traits type. There is
no reason to explicitly disallow `constexpr` operation. So mark all eligible
methods `constexpr`.

In addition, add some `static_assert()`s to the "quantized" test to check
constexpr operation.

For example, `FixedPointQTraits<...>::toFloat()` is `constexpr`, so this
enables the construction of `{U,}Q<...>` from the underlying quantized
value in `constexpr` contexts, which can be useful for example for
storing default values in e.g. `static constexpr` variables.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-03-20 08:35:17 +01:00

157 lines
3.3 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2026, Ideas on Board
*
* Dual Type and Quantizer tests
*/
#include "../src/ipa/libipa/quantized.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include <stdint.h>
#include "test.h"
using namespace std;
using namespace libcamera;
using namespace ipa;
struct BrightnessHueTraits {
using QuantizedType = uint8_t;
static QuantizedType fromFloat(float v)
{
int quantized = std::lround(v * 128.0f);
return std::clamp<int>(quantized, -128, 127);
}
static constexpr float toFloat(QuantizedType v)
{
return static_cast<float>(v) / 128.0f;
}
};
using BrightnessHueQuantizer = Quantized<BrightnessHueTraits>;
struct ContrastSaturationTraits {
using QuantizedType = uint8_t;
static QuantizedType fromFloat(float v)
{
int quantized = std::lround(v * 128.0f);
return std::clamp<int>(quantized, 0, 255);
}
static constexpr float toFloat(QuantizedType v)
{
return static_cast<float>(v) / 128.0f;
}
};
using ContrastSaturationQuantizer = Quantized<ContrastSaturationTraits>;
using BrightnessQ = BrightnessHueQuantizer;
using HueQ = BrightnessHueQuantizer;
using ContrastQ = ContrastSaturationQuantizer;
using SaturationQ = ContrastSaturationQuantizer;
class QuantizedTest : public Test
{
protected:
int run()
{
/* Test construction from float */
{
BrightnessQ b(0.5f);
if (b.quantized() != 64 || std::abs(b.value() - 0.5f) > 0.01f)
return TestFail;
}
/* Test construction from T */
{
ContrastQ c(uint8_t(128));
if (c.quantized() != 128 || std::abs(c.value() - 1.0f) > 0.01f)
return TestFail;
}
/*
* Only construction from the exact storage type or a float
* is permitted.
*/
static_assert(!std::is_constructible_v<BrightnessQ, unsigned int>);
static_assert(!std::is_constructible_v<BrightnessQ, int8_t>);
static_assert(!std::is_constructible_v<BrightnessQ, double>);
static_assert(!std::is_constructible_v<ContrastQ, int>);
static_assert(!std::is_constructible_v<ContrastQ, int8_t>);
static_assert(!std::is_constructible_v<ContrastQ, unsigned int>);
/* Test equality */
{
BrightnessQ b1(0.5f), b2(uint8_t(64));
if (!(b1 == b2))
return TestFail;
}
/* Test inequality */
{
BrightnessQ b1(0.5f), b2(-0.5f);
if (!(b1 != b2))
return TestFail;
}
/* Test copying */
{
BrightnessQ b1(0.25f);
BrightnessQ b2 = b1;
if (!(b1 == b2))
return TestFail;
}
/* Test assignment */
{
ContrastQ c1(1.5f);
ContrastQ c2(0.0f);
c2 = c1;
if (!(c1 == c2))
return TestFail;
}
/*
* Test construction from different floats mapping to same
* quantized value
*/
{
/* Two floats that have the same quantized value. */
const float f1 = 1.007f;
const float f2 = 1.008f;
ContrastQ c1(f1);
ContrastQ c2(f2);
/* Quantized values must match */
if (!(c1.quantized() == c2.quantized()))
return TestFail;
/* Float values must now match */
if (!(c1.value() == c2.value()))
return TestFail;
if (!(c1 == c2))
return TestFail;
}
/* Test constexpr operation */
{
constexpr BrightnessQ b1(uint8_t(1));
constexpr BrightnessQ b2(uint8_t(2));
static_assert(b1.quantized() == 1);
static_assert(b2.quantized() == 2);
static_assert(b1 != b2);
static_assert(!(b1 == b2));
}
return TestPass;
}
};
TEST_REGISTER(QuantizedTest)