summaryrefslogtreecommitdiffstats
path: root/media/img_utils
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2015-06-05 17:03:05 -0700
committerRuben Brunk <rubenbrunk@google.com>2015-06-16 09:51:20 -0700
commit0f212b73e47ef0e1fa39aa250ebabedb9d81a361 (patch)
treea05bb0a5893e85ddd2c77c59509fcaf52283603d /media/img_utils
parentbd974011599b6d4ff47c1cee36d617f191dc0c2f (diff)
downloadframeworks_av-0f212b73e47ef0e1fa39aa250ebabedb9d81a361.zip
frameworks_av-0f212b73e47ef0e1fa39aa250ebabedb9d81a361.tar.gz
frameworks_av-0f212b73e47ef0e1fa39aa250ebabedb9d81a361.tar.bz2
Add distortion correction opcodes in DngCreator.
Bug: 20491394 Change-Id: Ide932d49e620c7dc9a847bb5ddc8715d5f936bd5
Diffstat (limited to 'media/img_utils')
-rw-r--r--media/img_utils/include/img_utils/DngUtils.h37
-rw-r--r--media/img_utils/src/DngUtils.cpp97
2 files changed, 133 insertions, 1 deletions
diff --git a/media/img_utils/include/img_utils/DngUtils.h b/media/img_utils/include/img_utils/DngUtils.h
index 4389b02..3dcedc5 100644
--- a/media/img_utils/include/img_utils/DngUtils.h
+++ b/media/img_utils/include/img_utils/DngUtils.h
@@ -31,6 +31,7 @@ namespace android {
namespace img_utils {
#define NELEMS(x) ((int) (sizeof(x) / sizeof((x)[0])))
+#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
/**
* Utility class for building values for the OpcodeList tags specified
@@ -107,13 +108,49 @@ class ANDROID_API OpcodeListBuilder : public LightRefBase<OpcodeListBuilder> {
uint32_t mapPlanes,
const float* mapGains);
+ /**
+ * Add WarpRectilinear opcode for the given metadata parameters.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ virtual status_t addWarpRectilinearForMetadata(const float* kCoeffs,
+ uint32_t activeArrayWidth,
+ uint32_t activeArrayHeight,
+ float opticalCenterX,
+ float opticalCenterY);
+
+ /**
+ * Add a WarpRectilinear opcode.
+ *
+ * numPlanes - Number of planes included in this opcode.
+ * opticalCenterX, opticalCenterY - Normalized x,y coordinates of the sensor optical
+ * center relative to the top,left pixel of the produced images (e.g. [0.5, 0.5]
+ * gives a sensor optical center in the image center.
+ * kCoeffs - A list of coefficients for the polynomial equation representing the distortion
+ * correction. For each plane, 6 coefficients must be included:
+ * {k_r0, k_r1, k_r2, k_r3, k_t0, k_t1}. See the DNG 1.4 specification for an
+ * outline of the polynomial used here.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ virtual status_t addWarpRectilinear(uint32_t numPlanes,
+ double opticalCenterX,
+ double opticalCenterY,
+ const double* kCoeffs);
+
// TODO: Add other Opcode methods
protected:
static const uint32_t FLAG_OPTIONAL = 0x1u;
static const uint32_t FLAG_OPTIONAL_FOR_PREVIEW = 0x2u;
+ // Opcode IDs
enum {
+ WARP_RECTILINEAR_ID = 1,
GAIN_MAP_ID = 9,
+ };
+
+ // LSM mosaic indices
+ enum {
LSM_R_IND = 0,
LSM_GE_IND = 1,
LSM_GO_IND = 2,
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index d3b4a35..b213403 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -16,6 +16,10 @@
#include <img_utils/DngUtils.h>
+#include <inttypes.h>
+
+#include <math.h>
+
namespace android {
namespace img_utils {
@@ -229,7 +233,7 @@ status_t OpcodeListBuilder::addGainMap(uint32_t top,
err = mEndianOut.write(version, 0, NELEMS(version));
if (err != OK) return err;
- // Do not include optional flag for preview, as this can have a large effect on the output.
+ // Allow this opcode to be skipped if not supported
uint32_t flags = FLAG_OPTIONAL;
err = mEndianOut.write(&flags, 0, 1);
@@ -278,5 +282,96 @@ status_t OpcodeListBuilder::addGainMap(uint32_t top,
return OK;
}
+status_t OpcodeListBuilder::addWarpRectilinearForMetadata(const float* kCoeffs,
+ uint32_t activeArrayWidth,
+ uint32_t activeArrayHeight,
+ float opticalCenterX,
+ float opticalCenterY) {
+ if (activeArrayWidth <= 1 || activeArrayHeight <= 1) {
+ ALOGE("%s: Cannot add opcode for active array with dimensions w=%" PRIu32 ", h=%" PRIu32,
+ __FUNCTION__, activeArrayWidth, activeArrayHeight);
+ return BAD_VALUE;
+ }
+
+ double normalizedOCX = opticalCenterX / static_cast<double>(activeArrayWidth - 1);
+ double normalizedOCY = opticalCenterY / static_cast<double>(activeArrayHeight - 1);
+
+ normalizedOCX = CLAMP(normalizedOCX, 0, 1);
+ normalizedOCY = CLAMP(normalizedOCY, 0, 1);
+
+ // Conversion factors from Camera2 K factors to DNG spec. K factors:
+ //
+ // Note: these are necessary because our unit system assumes a
+ // normalized max radius of sqrt(2), whereas the DNG spec's
+ // WarpRectilinear opcode assumes a normalized max radius of 1.
+ // Thus, each K coefficient must include the domain scaling
+ // factor (the DNG domain is scaled by sqrt(2) to emulate the
+ // domain used by the Camera2 specification).
+
+ const double c_0 = sqrt(2);
+ const double c_1 = 2 * sqrt(2);
+ const double c_2 = 4 * sqrt(2);
+ const double c_3 = 8 * sqrt(2);
+ const double c_4 = 2;
+ const double c_5 = 2;
+
+ const double coeffs[] = { c_0 * kCoeffs[0],
+ c_1 * kCoeffs[1],
+ c_2 * kCoeffs[2],
+ c_3 * kCoeffs[3],
+ c_4 * kCoeffs[4],
+ c_5 * kCoeffs[5] };
+
+
+ return addWarpRectilinear(/*numPlanes*/1,
+ /*opticalCenterX*/normalizedOCX,
+ /*opticalCenterY*/normalizedOCY,
+ coeffs);
+}
+
+status_t OpcodeListBuilder::addWarpRectilinear(uint32_t numPlanes,
+ double opticalCenterX,
+ double opticalCenterY,
+ const double* kCoeffs) {
+
+ uint32_t opcodeId = WARP_RECTILINEAR_ID;
+
+ status_t err = mEndianOut.write(&opcodeId, 0, 1);
+ if (err != OK) return err;
+
+ uint8_t version[] = {1, 3, 0, 0};
+ err = mEndianOut.write(version, 0, NELEMS(version));
+ if (err != OK) return err;
+
+ // Allow this opcode to be skipped if not supported
+ uint32_t flags = FLAG_OPTIONAL;
+
+ err = mEndianOut.write(&flags, 0, 1);
+ if (err != OK) return err;
+
+ const uint32_t NUMBER_CENTER_ARGS = 2;
+ const uint32_t NUMBER_COEFFS = numPlanes * 6;
+ uint32_t totalSize = (NUMBER_CENTER_ARGS + NUMBER_COEFFS) * sizeof(double) + sizeof(uint32_t);
+
+ err = mEndianOut.write(&totalSize, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&numPlanes, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(kCoeffs, 0, NUMBER_COEFFS);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&opticalCenterX, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&opticalCenterY, 0, 1);
+ if (err != OK) return err;
+
+ mCount++;
+
+ return OK;
+}
+
} /*namespace img_utils*/
} /*namespace android*/