Author: post
Date: 2011-11-23 19:15:47 +0100 (Wed, 23 Nov 2011)
New Revision: 395
Modified:
RawSpeed/OrfDecoder.cpp
Log:
Read Olympus black level from Makernote, and compensate. Fixes long exposure
black level. Thanks to Sergey Pavlov for samples.
Modified: RawSpeed/OrfDecoder.cpp
===================================================================
--- RawSpeed/OrfDecoder.cpp 2011-11-23 18:13:09 UTC (rev 394)
+++ RawSpeed/OrfDecoder.cpp 2011-11-23 18:15:47 UTC (rev 395)
@@ -269,6 +269,71 @@
iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();
setMetaData(meta, make, model, "", iso);
+
+ TiffIFD *ImageProcessing = 0;
+ try {
+ data = mRootIFD->getIFDsWithTag(MAKERNOTE);
+
+ if (!data.empty()) {
+ TiffIFD* exif = data[0];
+ TiffEntry *makernoteEntry = exif->getEntry(MAKERNOTE);
+ const uchar8* makernote = makernoteEntry->getData();
+ FileMap makermap((uchar8*)&makernote[8], makernoteEntry->count - 8);
+ TiffParserOlympus makertiff(&makermap);
+ makertiff.parseData();
+ TiffEntry *blackEntry = 0;
+
+ // Try reading black level from tag 0x2040 (Olympus Imageprocessing)
+ if (makertiff.RootIFD()->hasEntryRecursive((TiffTag)0x2040)) {
+ try {
+ TiffEntry *imagep =
makertiff.RootIFD()->getEntryRecursive((TiffTag)0x2040);
+
+ int32 offset;
+ const uchar8* data = imagep->getData();
+ if (makertiff.tiff_endian = makertiff.getHostEndian())
+ offset = *(int32*)data;
+ else
+ offset = (unsigned int)data[0] << 24 | (unsigned int)data[1] << 16
| (unsigned int)data[2] << 8 | (unsigned int)data[3];
+
+ // It seems like Olympus doesn't mind data pointing out of the
makernote,
+ // so we give it the entire remaining file
+ FileMap makermap2((uchar8*)&makernote[0],
mFile->getSize()-makernoteEntry->getDataOffset());
+ if (makertiff.getHostEndian() == makertiff.tiff_endian)
+ ImageProcessing = new TiffIFD(&makermap2, offset);
+ else
+ ImageProcessing = new TiffIFDBE(&makermap2, offset);
+ blackEntry = ImageProcessing->getEntry((TiffTag)0x600);
+ } catch (TiffParserException) {
+ }
+ }
+
+ // Otherwise try 0x1012
+ if (!blackEntry &&
makertiff.RootIFD()->hasEntryRecursive((TiffTag)0x1012)) {
+ blackEntry = makertiff.RootIFD()->getEntryRecursive((TiffTag)0x1012);
+ }
+
+ // Order is assumed to be RGGB
+ if (blackEntry && blackEntry->count == 4) {
+ const ushort16* black = blackEntry->getShortArray();
+ for (int i = 0; i < 4; i++) {
+ if (mRaw->cfa.getColorAt(i&1, i>>1) == CFA_RED)
+ mRaw->blackLevelSeparate[i] = black[0];
+ else if (mRaw->cfa.getColorAt(i&1, i>>1) == CFA_BLUE)
+ mRaw->blackLevelSeparate[i] = black[3];
+ else if (mRaw->cfa.getColorAt(i&1, i>>1) == CFA_GREEN && i<2)
+ mRaw->blackLevelSeparate[i] = black[1];
+ else if (mRaw->cfa.getColorAt(i&1, i>>1) == CFA_GREEN)
+ mRaw->blackLevelSeparate[i] = black[2];
+ }
+ // Adjust whitelevel based on the read black (we assume the dynamic
range is the same)
+ mRaw->whitePoint -= (mRaw->blackLevel - mRaw->blackLevelSeparate[0]);
+ }
+ }
+ } catch (TiffParserException) {
+ }
+ if (ImageProcessing)
+ delete ImageProcessing;
+
}
} // namespace RawSpeed
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit