@@ -23,7 +23,7 @@ class DebayerGeometryTest : public Test
protected:
int run() override
{
- if (testProjection() || testCrop())
+ if (testProjection() || testCrop() || testSensorCrop())
return TestFail;
return TestPass;
@@ -123,6 +123,48 @@ private:
return TestPass;
}
+
+ int testSensorCrop()
+ {
+ static const struct {
+ Rectangle crop;
+ Size input;
+ Rectangle analog;
+ Rectangle active;
+ Transform transform;
+ Rectangle expected;
+ } cases[] = {
+ /* GPU scaling keeps the full visible sensor region. */
+ { { 4, 6, 1920, 1080 }, { 1928, 1092 }, { 0, 0, 1928, 1092 }, { 0, 0, 1928, 1092 }, Transform::Identity, { 4, 6, 1920, 1080 } },
+ /* Sensor crop offsets and 2x binning use native pixels. */
+ { { 4, 6, 1920, 1080 }, { 1928, 1092 }, { 100, 200, 3856, 2184 }, { 8, 8, 4000, 3000 }, Transform::Identity, { 100, 204, 3840, 2160 } },
+ /* CPU debayering crops to output size without scaling. */
+ { { 324, 186, 1280, 720 }, { 1928, 1092 }, { 100, 200, 3856, 2184 }, { 8, 8, 4000, 3000 }, Transform::Identity, { 740, 564, 2560, 1440 } },
+ /* Preserve an odd image boundary before statistics alignment. */
+ { { 2, 5, 1924, 1082 }, { 1928, 1092 }, { 0, 0, 3856, 2184 }, { 0, 0, 3856, 2184 }, Transform::Identity, { 4, 10, 3848, 2164 } },
+ /* Undo sensor flips before reporting the native rectangle. */
+ { { 2, 4, 20, 10 }, { 100, 60 }, { 10, 20, 200, 120 }, { 2, 4, 300, 200 }, Transform::HFlip, { 164, 24, 40, 20 } },
+ { { 2, 4, 20, 10 }, { 100, 60 }, { 10, 20, 200, 120 }, { 2, 4, 300, 200 }, Transform::VFlip, { 12, 108, 40, 20 } },
+ { { 2, 4, 20, 10 }, { 100, 60 }, { 10, 20, 200, 120 }, { 2, 4, 300, 200 }, Transform::HVFlip, { 164, 108, 40, 20 } },
+ /* Transposition is undone before the flip. */
+ { { 4, 2, 10, 20 }, { 60, 100 }, { 10, 20, 200, 120 }, { 2, 4, 300, 200 }, Transform::Rot270, { 164, 24, 40, 20 } },
+ /* Fractional native coordinates and sizes truncate independently. */
+ { { 1, 1, 3, 3 }, { 8, 8 }, { 10, 20, 12, 12 }, { 2, 4, 30, 40 }, Transform::Identity, { 9, 17, 4, 4 } },
+ };
+
+ for (const auto &entry : cases) {
+ Rectangle crop = debayerCropToSensor(entry.crop, entry.input,
+ entry.analog, entry.active,
+ entry.transform);
+ if (crop != entry.expected) {
+ std::cerr << "Sensor mapping of " << entry.crop << " in " << entry.input
+ << " is " << crop << ", expected " << entry.expected << std::endl;
+ return TestFail;
+ }
+ }
+
+ return TestPass;
+ }
};
TEST_REGISTER(DebayerGeometryTest)