Author: post
Date: 2010-07-05 23:05:27 +0200 (Mon, 05 Jul 2010)
New Revision: 249
Modified:
RawSpeed/Cr2Decoder.cpp
RawSpeed/TiffIFD.cpp
RawSpeed/TiffIFD.h
RawSpeed/TiffIFDBE.cpp
Log:
Attempt to read makernote and private dng data and add them to the TIFF
structure. Unreadable/invalid structures are read as always. Also fixes very
minor leak in big endian files.
Modified: RawSpeed/Cr2Decoder.cpp
===================================================================
--- RawSpeed/Cr2Decoder.cpp 2010-07-01 20:20:18 UTC (rev 248)
+++ RawSpeed/Cr2Decoder.cpp 2010-07-05 21:05:27 UTC (rev 249)
@@ -164,17 +164,8 @@
// Interpolate and convert sRaw data.
void Cr2Decoder::sRawInterpolate() {
- vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MAKERNOTE);
+ vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0x4001);
if (data.empty())
- ThrowRDE("CR2 sRaw: Makernote not found");
-
- TiffIFD* exif = data[0];
- TiffEntry *makernoteEntry = exif->getEntry(MAKERNOTE);
- TiffParserHeaderless makertiff(mFile, mRootIFD->endian);
- makertiff.parseData(makernoteEntry->getDataOffset());
-
- data = makertiff.RootIFD()->getIFDsWithTag((TiffTag)0x4001);
- if (data.empty())
ThrowRDE("CR2 sRaw: Unable to locate WB info.");
const ushort16 *wb_data =
data[0]->getEntry((TiffTag)0x4001)->getShortArray();
Modified: RawSpeed/TiffIFD.cpp
===================================================================
--- RawSpeed/TiffIFD.cpp 2010-07-01 20:20:18 UTC (rev 248)
+++ RawSpeed/TiffIFD.cpp 2010-07-05 21:05:27 UTC (rev 249)
@@ -1,5 +1,6 @@
#include "StdAfx.h"
#include "TiffIFD.h"
+#include "TiffParser.h"
/*
RawSpeed - RAW file decoder.
@@ -47,12 +48,31 @@
for (uint32 i = 0; i < entries; i++) {
TiffEntry *t = new TiffEntry(f, offset + 2 + i*12);
- if (t->tag == SUBIFDS || t->tag == EXIFIFDPOINTER) { // subIFD tag
- const unsigned int* sub_offsets = t->getIntArray();
- for (uint32 j = 0; j < t->count; j++) {
- mSubIFD.push_back(new TiffIFD(f, sub_offsets[j]));
+ if (t->tag == SUBIFDS || t->tag == EXIFIFDPOINTER || t->tag ==
DNGPRIVATEDATA || t->tag == MAKERNOTE) { // subIFD tag
+ if (t->tag == DNGPRIVATEDATA) {
+ try {
+ TiffIFD *maker_ifd = parseDngPrivateData(t);
+ mSubIFD.push_back(maker_ifd);
+ delete(t);
+ } catch (TiffParserException e) {
+ // Unparsable private data are added as entries
+ mEntry[t->tag] = t;
+ }
+ } else if (t->tag == MAKERNOTE) {
+ try {
+ mSubIFD.push_back(new TiffIFD(f, t->getDataOffset()));
+ delete(t);
+ } catch (TiffParserException e) {
+ // Unparsable makernotes are added as entries
+ mEntry[t->tag] = t;
+ }
+ } else {
+ const unsigned int* sub_offsets = t->getIntArray();
+ for (uint32 j = 0; j < t->count; j++) {
+ mSubIFD.push_back(new TiffIFD(f, sub_offsets[j]));
+ }
+ delete(t);
}
- delete(t);
} else { // Store as entry
mEntry[t->tag] = t;
}
@@ -60,6 +80,72 @@
nextIFD = *(int*)f->getData(offset + 2 + entries * 12);
}
+TiffIFD* TiffIFD::parseDngPrivateData(TiffEntry *t) {
+ /*
+ 1. Six bytes containing the zero-terminated string "Adobe". (The DNG
specification calls for the DNGPrivateData tag to start with an ASCII string
identifying the creator/format).
+ 2. 4 bytes: an ASCII string ("MakN" for a Makernote), indicating what sort
of data is being stored here. Note that this is not zero-terminated.
+ 3. A four-byte count (number of data bytes following); this is the length of
the original MakerNote data. (This is always in "most significant byte first"
format).
+ 4. 2 bytes: the byte-order indicator from the original file (the usual
'MM'/4D4D or 'II'/4949).
+ 5. 4 bytes: the original file offset for the MakerNote tag data (stored
according to the byte order given above).
+ 6. The contents of the MakerNote tag. This is a simple byte-for-byte copy,
with no modification.
+ */
+ uint32 size = t->count;
+ const uchar8 *data = t->getData();
+ string id((const char*)data);
+ if (id.compare("Adobe"))
+ ThrowTPE("Not Adobe Private data");
+
+ data+=6;
+ if (!(data[0] == 'M' && data[1] == 'a' && data[2] == 'k' &&data[3] == 'N' ))
+ ThrowTPE("Not Makernote");
+
+ data+=4;
+ uint32 count;
+ if (big == getHostEndianness())
+ count = *(uint32*)data;
+ else
+ count = (unsigned int)data[0] << 24 | (unsigned int)data[1] << 16 |
(unsigned int)data[2] << 8 | (unsigned int)data[3];
+
+ data+=4;
+ CHECKSIZE(count);
+ Endianness makernote_endian;
+ if (data[0] == 0x49 && data[1] == 0x49)
+ makernote_endian = little;
+ else if (data[0] == 0x4D && data[1] == 0x4D)
+ makernote_endian = big;
+ else
+ ThrowTPE("Cannot determine endianess of DNG makernote");
+
+ data+=2;
+ uint32 org_offset;
+
+ if (big == getHostEndianness())
+ org_offset = *(uint32*)data;
+ else
+ org_offset = (unsigned int)data[0] << 24 | (unsigned int)data[1] << 16 |
(unsigned int)data[2] << 8 | (unsigned int)data[3];
+
+ data+=4;
+ /* Create fake tiff with original offsets */
+ uchar8* maker_data = new uchar8[org_offset+count];
+ memcpy(&maker_data[org_offset],data, count);
+ FileMap *maker_map = new FileMap(maker_data, org_offset+count);
+
+ TiffIFD *maker_ifd;
+ try {
+ if (makernote_endian == getHostEndianness())
+ maker_ifd = new TiffIFD(maker_map, org_offset);
+ else
+ maker_ifd = new TiffIFDBE(maker_map, org_offset);
+ } catch (TiffParserException e) {
+ delete[] maker_data;
+ delete maker_map;
+ throw e;
+ }
+ delete[] maker_data;
+ delete maker_map;
+ return maker_ifd;
+}
+
TiffIFD::~TiffIFD(void) {
for (map<TiffTag, TiffEntry*>::iterator i = mEntry.begin(); i !=
mEntry.end(); ++i) {
delete((*i).second);
Modified: RawSpeed/TiffIFD.h
===================================================================
--- RawSpeed/TiffIFD.h 2010-07-01 20:20:18 UTC (rev 248)
+++ RawSpeed/TiffIFD.h 2010-07-05 21:05:27 UTC (rev 249)
@@ -42,6 +42,7 @@
bool hasEntry(TiffTag tag);
bool hasEntryRecursive(TiffTag tag);
TiffEntry* getEntryRecursive(TiffTag tag);
+ TiffIFD* parseDngPrivateData(TiffEntry *t);
Endianness endian;
protected:
int nextIFD;
Modified: RawSpeed/TiffIFDBE.cpp
===================================================================
--- RawSpeed/TiffIFDBE.cpp 2010-07-01 20:20:18 UTC (rev 248)
+++ RawSpeed/TiffIFDBE.cpp 2010-07-05 21:05:27 UTC (rev 249)
@@ -41,10 +41,30 @@
for (int i = 0; i < entries; i++) {
TiffEntryBE *t = new TiffEntryBE(f, offset + 2 + i*12);
- if (t->tag == SUBIFDS || t->tag == EXIFIFDPOINTER) { // subIFD tag
- const unsigned int* sub_offsets = t->getIntArray();
- for (uint32 j = 0; j < t->count; j++) {
- mSubIFD.push_back(new TiffIFDBE(f, sub_offsets[j]));
+ if (t->tag == SUBIFDS || t->tag == EXIFIFDPOINTER || t->tag ==
DNGPRIVATEDATA || t->tag == MAKERNOTE) { // subIFD tag
+ if (t->tag == DNGPRIVATEDATA) {
+ try {
+ TiffIFD *maker_ifd = parseDngPrivateData(t);
+ mSubIFD.push_back(maker_ifd);
+ delete(t);
+ } catch (TiffParserException e) {
+ // Unparsable private data are added as entries
+ mEntry[t->tag] = t;
+ }
+ } else if (t->tag == MAKERNOTE) {
+ try {
+ mSubIFD.push_back(new TiffIFDBE(f, t->getDataOffset()));
+ delete(t);
+ } catch (TiffParserException e) {
+ // Unparsable makernotes are added as entries
+ mEntry[t->tag] = t;
+ }
+ } else {
+ const unsigned int* sub_offsets = t->getIntArray();
+ for (uint32 j = 0; j < t->count; j++) {
+ mSubIFD.push_back(new TiffIFDBE(f, sub_offsets[j]));
+ }
+ delete(t);
}
} else { // Store as entry
mEntry[t->tag] = t;
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit