Merge "DngCreator: Improve BlackLevel, fix thumbnail metadata" into nyc-dev
am: 8a35cbf45b
* commit '8a35cbf45bce1d09ab0ef222331edf811f50985d':
DngCreator: Improve BlackLevel, fix thumbnail metadata
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user