test: libipa: Add tests for Quantized types
Provide use case tests for the Quantized types to ensure construction and usages are consistent and work as expected. Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
@@ -5,6 +5,7 @@ libipa_test = [
|
||||
{'name': 'histogram', 'sources': ['histogram.cpp']},
|
||||
{'name': 'interpolator', 'sources': ['interpolator.cpp']},
|
||||
{'name': 'pwl', 'sources': ['pwl.cpp'] },
|
||||
{'name': 'quantized', 'sources': ['quantized.cpp']},
|
||||
]
|
||||
|
||||
foreach test : libipa_test
|
||||
|
||||
145
test/ipa/libipa/quantized.cpp
Normal file
145
test/ipa/libipa/quantized.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* 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 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 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;
|
||||
}
|
||||
|
||||
return TestPass;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_REGISTER(QuantizedTest)
|
||||
Reference in New Issue
Block a user