Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a35cbf4 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Merge "DngCreator: Improve BlackLevel, fix thumbnail metadata" into nyc-dev

parents 9eb7190a 8069b1f2
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -137,6 +137,11 @@ public final class DngCreator implements AutoCloseable {
            throw new IllegalArgumentException("Orientation " + orientation +
                    " is not a valid EXIF orientation value");
        }
        // ExifInterface and TIFF/EP spec differ on definition of
        // "Unknown" orientation; other values map directly
        if (orientation == ExifInterface.ORIENTATION_UNDEFINED) {
            orientation = TAG_ORIENTATION_UNKNOWN;
        }
        nativeSetOrientation(orientation);
        return this;
    }
@@ -443,7 +448,7 @@ public final class DngCreator implements AutoCloseable {
    private static final String GPS_LONG_REF_WEST = "W";

    private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd";
    private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd kk:mm:ss";
    private static final String TIFF_DATETIME_FORMAT = "yyyy:MM:dd HH:mm:ss";
    private static final DateFormat sExifGPSDateStamp = new SimpleDateFormat(GPS_DATE_FORMAT_STR);
    private static final DateFormat sDateTimeStampFormat =
            new SimpleDateFormat(TIFF_DATETIME_FORMAT);
@@ -458,6 +463,9 @@ public final class DngCreator implements AutoCloseable {
    private static final int DEFAULT_PIXEL_STRIDE = 2; // bytes per sample
    private static final int BYTES_PER_RGB_PIX = 3; // byts per pixel

    // TIFF tag values needed to map between public API and TIFF spec
    private static final int TAG_ORIENTATION_UNKNOWN = 9;

    /**
     * Offset, rowStride, and pixelStride are given in bytes.  Height and width are given in pixels.
     */
+34 −10
Original line number Diff line number Diff line
@@ -80,6 +80,13 @@ using namespace img_utils;
        return nullptr; \
    }

#define BAIL_IF_EXPR_RET_NULL_SP(expr, jnienv, tagId, writer) \
    if (expr) { \
        jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \
                "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \
        return nullptr; \
    }


#define ANDROID_DNGCREATOR_CTX_JNI_ID     "mNativeContext"

@@ -195,8 +202,8 @@ private:
NativeContext::NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result) :
        mCharacteristics(std::make_shared<CameraMetadata>(characteristics)),
        mResult(std::make_shared<CameraMetadata>(result)), mThumbnailWidth(0),
        mThumbnailHeight(0), mOrientation(0), mThumbnailSet(false), mGpsSet(false),
        mDescriptionSet(false), mCaptureTimeSet(false) {}
        mThumbnailHeight(0), mOrientation(TAG_ORIENTATION_UNKNOWN), mThumbnailSet(false),
        mGpsSet(false), mDescriptionSet(false), mCaptureTimeSet(false) {}

NativeContext::~NativeContext() {}

@@ -1096,7 +1103,7 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image

    {
        // Set orientation
        uint16_t orientation = 1; // Normal
        uint16_t orientation = TAG_ORIENTATION_NORMAL;
        BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0),
                env, TAG_ORIENTATION, writer);
    }
@@ -1138,12 +1145,27 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image
    }

    {
        // Set blacklevel tags
        // Set blacklevel tags, using dynamic black level if available
        camera_metadata_entry entry =
                characteristics.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
        BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_BLACKLEVEL, writer);
        const uint32_t* blackLevel = reinterpret_cast<const uint32_t*>(entry.data.i32);
        BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, entry.count, blackLevel,
                results.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
        uint32_t blackLevelRational[8] = {0};
        if (entry.count != 0) {
            BAIL_IF_EXPR_RET_NULL_SP(entry.count != 4, env, TAG_BLACKLEVEL, writer);
            for (size_t i = 0; i < entry.count; i++) {
                blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.f[i] * 100);
                blackLevelRational[i * 2 + 1] = 100;
            }
        } else {
            // Fall back to static black level which is guaranteed
            entry = characteristics.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
            BAIL_IF_EXPR_RET_NULL_SP(entry.count != 4, env, TAG_BLACKLEVEL, writer);
            for (size_t i = 0; i < entry.count; i++) {
                blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.i32[i]);
                blackLevelRational[i * 2 + 1] = 1;
            }

        }
        BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, 4, blackLevelRational,
                TIFF_IFD_0), env, TAG_BLACKLEVEL, writer);

        uint16_t repeatDim[2] = {2, 2};
@@ -1913,8 +1935,10 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image

        {
            // Set bits per sample
            uint16_t bits = BITS_PER_RGB_SAMPLE;
            BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0),
            uint16_t bits[SAMPLES_PER_RGB_PIXEL];
            for (int i = 0; i < SAMPLES_PER_RGB_PIXEL; i++) bits[i] = BITS_PER_RGB_SAMPLE;
            BAIL_IF_INVALID_RET_NULL_SP(
                    writer->addEntry(TAG_BITSPERSAMPLE, SAMPLES_PER_RGB_PIXEL, bits, TIFF_IFD_0),
                    env, TAG_BITSPERSAMPLE, writer);
        }