[2/6] test: libipa: Add tests for Quantizers
diff mbox series

Message ID 20251026233048.175689-3-kieran.bingham@ideasonboard.com
State New
Headers show
Series
  • libipa: Introduce a Quantized type
Related show

Commit Message

Kieran Bingham Oct. 26, 2025, 11:30 p.m. UTC
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 test/ipa/libipa/meson.build   |   1 +
 test/ipa/libipa/quantized.cpp | 149 ++++++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)
 create mode 100644 test/ipa/libipa/quantized.cpp

Patch
diff mbox series

diff --git a/test/ipa/libipa/meson.build b/test/ipa/libipa/meson.build
index 2070bed70222..c3e255871f4f 100644
--- a/test/ipa/libipa/meson.build
+++ b/test/ipa/libipa/meson.build
@@ -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
diff --git a/test/ipa/libipa/quantized.cpp b/test/ipa/libipa/quantized.cpp
new file mode 100644
index 000000000000..51db62a1b88a
--- /dev/null
+++ b/test/ipa/libipa/quantized.cpp
@@ -0,0 +1,149 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2025, Ideas on Board
+ *
+ * Dual Type and Quantizer tests
+ */
+
+#include "../src/ipa/libipa/quantized.h"
+
+#include <algorithm>
+#include <cmath>
+#include <iostream>
+#include <map>
+#include <stdint.h>
+
+#include "test.h"
+
+using namespace std;
+using namespace libcamera;
+using namespace ipa;
+
+class BrightnessHueQuantizer : public Quantizer<int8_t>
+{
+public:
+	BrightnessHueQuantizer(float val) { set(val); }
+	BrightnessHueQuantizer(int8_t val) { set(val); }
+
+	int8_t fromFloat(float v) const override
+	{
+		int quantized = std::lround(v * 128.0f);
+		return static_cast<int8_t>(std::clamp<int>(quantized, -128, 127));
+	}
+
+	float toFloat(int8_t v) const override
+	{
+		return static_cast<float>(v) / 128.0f;
+	}
+};
+
+class ContrastSaturationQuantizer : public Quantizer<uint8_t>
+{
+public:
+	ContrastSaturationQuantizer(float val) { set(val); }
+	ContrastSaturationQuantizer(uint8_t val) { set(val); }
+
+	uint8_t fromFloat(float v) const override
+	{
+		int quantized = std::lround(v * 128.0f);
+		return static_cast<uint8_t>(std::clamp<int>(quantized, 0, 255));
+	}
+
+	float toFloat(uint8_t v) const override
+	{
+		return static_cast<float>(v) / 128.0f;
+	}
+};
+
+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;
+		}
+
+		/*
+		 * Test construction from non-float/non-T type (Expected Fail)
+		 * These should be a compile-time error if uncommented:
+		 */
+		// BrightnessQ bad1(15); // overloaded ‘BrightnessHueQuantizer(int)’ is ambiguous
+		// BrightnessQ bad2(0xff); // overloaded ‘BrightnessHueQuantizer(int)’ is ambiguous
+		// ContrastQ bad3(0x33); // overloaded ‘ContrastSaturationQuantizer(int)’ is ambiguous
+		// ContrastQ bad4(55U); // overloaded ‘ContrastSaturationQuantizer(unsigned int)’ is ambiguous
+
+		/* Test equality */
+		{
+			BrightnessQ b1(0.5f), b2((int8_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 moving */
+		{
+			BrightnessQ b1(0.25f);
+			BrightnessQ b2 = std::move(b1); // Allow move semantics
+			if (b2.value() != 0.25f)
+				return TestFail;
+		}
+
+		/* Test assignment */
+		{
+			ContrastQ c1(1.5f);
+			ContrastQ c2(0.0f);
+			c2 = c1;
+			if (!(c1 == c2))
+				return TestFail;
+		}
+
+		/* Test assignment / storage in generic type */
+		{
+			ContrastQ c(1.5f);
+			Quantized<uint8_t> q;
+
+			q = c;
+			if (q.value() != c.value())
+				return TestFail;
+
+			if (q.quantized() != c.quantized())
+				return TestFail;
+		}
+
+		std::cout << "Quantised tests passed successfully." << std::endl;
+
+		return TestPass;
+	}
+};
+
+TEST_REGISTER(QuantizedTest)