[libcamera-devel] [PATCH 1/5] libcamera: Add Transform class
David Plowman
david.plowman at raspberrypi.com
Wed Jul 29 11:31:50 CEST 2020
Add implementation of 2d plane transforms, and include a Transform
field in the CameraConfiguration to record the application's choice of
image transform for this session.
---
include/libcamera/camera.h | 3 +
include/libcamera/meson.build | 1 +
include/libcamera/transform.h | 193 ++++++++++++++++++++++++++++++++++
3 files changed, 197 insertions(+)
create mode 100644 include/libcamera/transform.h
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 4d1a4a9..fd9355e 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -16,6 +16,7 @@
#include <libcamera/request.h>
#include <libcamera/signal.h>
#include <libcamera/stream.h>
+#include <libcamera/transform.h>
namespace libcamera {
@@ -60,6 +61,8 @@ public:
bool empty() const;
std::size_t size() const;
+ Transform userTransform;
+
protected:
CameraConfiguration();
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index cdb8e03..7fae5e5 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -19,6 +19,7 @@ libcamera_public_headers = files([
'span.h',
'stream.h',
'timer.h',
+ 'transform.h',
])
include_dir = join_paths(libcamera_include_dir, 'libcamera')
diff --git a/include/libcamera/transform.h b/include/libcamera/transform.h
new file mode 100644
index 0000000..cfd5026
--- /dev/null
+++ b/include/libcamera/transform.h
@@ -0,0 +1,193 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * transform.h - Implementation of 2d plane transforms
+ */
+
+#ifndef __LIBCAMERA_TRANSFORM_H__
+#define __LIBCAMERA_TRANSFORM_H__
+
+#include <string>
+
+namespace libcamera {
+
+class Transform
+{
+public:
+ constexpr Transform()
+ : Transform(Identity)
+ {
+ }
+
+ constexpr static Transform identity()
+ {
+ return Transform(Identity);
+ }
+
+ constexpr static Transform rot0()
+ {
+ return identity();
+ }
+
+ constexpr static Transform hflip()
+ {
+ return Transform(HFlip);
+ }
+
+ constexpr static Transform vflip()
+ {
+ return Transform(VFlip);
+ }
+
+ constexpr static Transform hvflip()
+ {
+ return Transform(HVFlip);
+ }
+
+ constexpr static Transform rot180()
+ {
+ return hvflip();
+ }
+
+ constexpr static Transform transpose()
+ {
+ return Transform(Transpose);
+ }
+
+ constexpr static Transform rot270()
+ {
+ return Transform(Rot270);
+ }
+
+ constexpr static Transform rot90()
+ {
+ return Transform(Rot90);
+ }
+
+ constexpr static Transform rot180Transpose()
+ {
+ return Transform(Rot180Transpose);
+ }
+
+ constexpr static Transform hvflipTranspose()
+ {
+ return rot180Transpose();
+ }
+
+ constexpr static bool rotation(int32_t angle, Transform &xfm)
+ {
+ bool success = true;
+ angle = angle % 360;
+ if (angle < 0)
+ angle += 360;
+
+ if (angle == 0)
+ xfm = identity();
+ else if (angle == 90)
+ xfm = rot90();
+ else if (angle == 180)
+ xfm = rot180();
+ else if (angle == 270)
+ xfm = rot270();
+ else
+ success = false;
+
+ return success;
+ }
+
+ constexpr bool rotation(int32_t &angle) const
+ {
+ bool success = true;
+
+ if (type_ == Identity)
+ angle = 0;
+ else if (type_ == Rot90)
+ angle = 90;
+ else if (type_ == HVFlip)
+ angle = 180;
+ else if (type_ == Rot270)
+ angle = 270;
+ else
+ success = false;
+
+ return success;
+ }
+
+ constexpr bool contains(Transform xfm) const
+ {
+ return (type_ & xfm.type_) == xfm.type_;
+ }
+
+ constexpr Transform inverse() const
+ {
+ /* They're all self-inverses, except for Rot90 and Rot270. */
+ const Type inverses[] = { Identity, HFlip, VFlip, HVFlip,
+ Transpose, Rot90, Rot270, Rot180Transpose };
+
+ return Transform(inverses[type_]);
+ }
+
+ constexpr Transform operator*(Transform xfm) const
+ {
+ /*
+ * Reorder the operations so that we imagine doing xfm's transpose
+ * (if any) after our flips. The effect is to swap our hflips for
+ * vflips and vice versa, after which we can just xor all the bits.
+ */
+ int reorderedType = type_;
+ if (xfm.type_ & Transpose)
+ reorderedType = (type_ & 4) | ((type_ & 1) << 1) | ((type_ & 2) >> 1);
+
+ return Transform((Type)(reorderedType ^ xfm.type_));
+ }
+
+ bool operator==(Transform xfm) const
+ {
+ return type_ == xfm.type_;
+ }
+
+ bool operator!=(Transform xfm) const
+ {
+ return !(*this == xfm);
+ }
+
+ std::string toString() const
+ {
+ char const *strings[] = {
+ "identity",
+ "hflip",
+ "vflip",
+ "hvflip",
+ "transpose",
+ "rot270",
+ "rot90",
+ "rot180transpose"
+ };
+ return strings[type_];
+ }
+
+private:
+ enum Type : int {
+ Identity = 0,
+ HFlip = 1,
+ VFlip = 2,
+ HVFlip = HFlip | VFlip,
+ Transpose = 4,
+ Rot270 = HFlip | Transpose,
+ Rot90 = VFlip | Transpose,
+ Rot180Transpose = HFlip | VFlip | Transpose
+ };
+
+ constexpr Transform(Type type)
+ : type_(type)
+ {
+ }
+
+ Type type_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_TRANSFORM_H__ */
+
--
2.20.1
More information about the libcamera-devel
mailing list