Solving issue 2197: "Pentax K-3 support"

This commit is contained in:
natureh.510
2014-01-29 18:38:36 +01:00
parent 82698ff15f
commit 38eb850a0a
4 changed files with 560 additions and 86 deletions

View File

@@ -23,7 +23,7 @@
#include <cstring>
#include <ctime>
#include <sstream>
#include <stdint.h>
#include <stdint.h>
#include "../rtgui/cacheimagedata.h"
#include "rtexif.h"
@@ -87,7 +87,7 @@ TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib*
TagDirectory::~TagDirectory () {
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
delete tags[i];
}
@@ -101,7 +101,7 @@ public:
void TagDirectory::sort () {
std::sort (tags.begin(), tags.end(), CompareTags());
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->isDirectory())
for (int j=0; tags[i]->getDirectory(j); j++)
tags[i]->getDirectory(j)->sort ();
@@ -167,7 +167,7 @@ void TagDirectory::printAll (unsigned int level) const {
prefixStr[i] = '\0';
// recursively iterate over the tag list
for (size_t i=0; i<tags.size(); i++) {
for (size_t i=0; i<tags.size(); i++) {
std::string name = tags[i]->nameToString ();
if (tags[i]->isDirectory())
for (int j=0; tags[i]->getDirectory(j); j++) {
@@ -315,7 +315,7 @@ void TagDirectory::addTagFront (Tag* tag) {
void TagDirectory::replaceTag (Tag* tag) {
// look up if it already exists:
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->getID()==tag->getID()) {
delete tags[i];
tags[i] = tag;
@@ -326,7 +326,7 @@ void TagDirectory::replaceTag (Tag* tag) {
Tag* TagDirectory::getTag (int ID) const {
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->getID()==ID)
return tags[i];
return NULL;
@@ -431,14 +431,14 @@ bool TagDirectory::getXMPTagValue(const char* name, char* value) const {
}
void TagDirectory::keepTag (int ID) {
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->getID()==ID) tags[i]->setKeep(true);
}
int TagDirectory::calculateSize () {
int size = 2; // space to store the number of tags
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->getKeep())
size += 12 + tags[i]->calculateSize ();
@@ -449,7 +449,7 @@ int TagDirectory::calculateSize () {
TagDirectory* TagDirectory::clone (TagDirectory* parent) {
TagDirectory* td = new TagDirectory (parent, attribs, order);
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
td->tags.push_back (tags[i]->clone (td));
return td;
}
@@ -459,7 +459,7 @@ int TagDirectory::write (int start, unsigned char* buffer) {
int size = calculateSize ();
int tagnum = 0;
int nondirspace = 0;
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->getKeep()) {
tagnum++;
if (!tags[i]->isDirectory())
@@ -471,7 +471,7 @@ int TagDirectory::write (int start, unsigned char* buffer) {
sset2 (tagnum, buffer+start, order);
pos += 2;
int maxPos = start + size;
for (size_t i=0; i<tags.size(); i++) {
for (size_t i=0; i<tags.size(); i++) {
if (tags[i]->getKeep()) {
if (!tags[i]->isDirectory())
nextValOffs = tags[i]->write (pos, nextValOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset
@@ -493,7 +493,7 @@ void TagDirectory::applyChange (std::string name, std::string value) {
if (dp==std::string::npos) {
Tag* t = NULL;
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->nameToString()==fseg) {
t = tags[i];
break;
@@ -526,7 +526,7 @@ void TagDirectory::applyChange (std::string name, std::string value) {
std::string basename = fseg.substr (0,dp1);
Tag* t = NULL;
int dirnum = -1;
for (size_t i=0; i<tags.size(); i++)
for (size_t i=0; i<tags.size(); i++)
if (tags[i]->isDirectory()) {
for (int j=0; tags[i]->getDirectory(j); j++) {
if (tags[i]->nameToString(j) == fseg) {
@@ -737,11 +737,10 @@ Tag::Tag (TagDirectory* p, FILE* f, int base)
default:
goto defsubdirs;
}
}else if (!strncmp(make, "PENTAX", 6)) {
}else if ((!strncmp(make, "PENTAX", 6)) || (!strncmp(make, "RICOH", 5) && !strncmp(model, "PENTAX", 6))) { // Either the former Pentax brand or the RICOH brand + PENTAX model"
switch( tag ){
case 0x005c:
case 0x007d:
case 0x0205:
case 0x0206:
case 0x0208:
case 0x0216:
directory = new TagDirectory*[2];
@@ -755,6 +754,36 @@ Tag::Tag (TagDirectory* p, FILE* f, int base)
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,LONG , attrib->subdirAttribs, order);
makerNoteKind = TABLESUBDIR;
break;
case 0x005c:
directory = new TagDirectory*[2];
directory[1] = NULL;
if (count == 4) // SRInfo
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxSRInfoAttribs, order);
else if (count == 2) // SRInfo2
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxSRInfo2Attribs, order);
else {
// Unknown SRInfo
delete directory;
directory = NULL;
}
makerNoteKind = TABLESUBDIR;
break;
case 0x0206:
directory = new TagDirectory*[2];
directory[1] = NULL;
if (count == 21) // AEInfo2
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfo2Attribs, order);
else if (count == 48) // AEInfo3
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfo3Attribs, order);
else if (count <= 25) // AEInfo
directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfoAttribs, order);
else {
// Unknown AEInfo
delete directory;
directory = NULL;
}
makerNoteKind = TABLESUBDIR;
break;
case 0x0207:
{ // There are 2 format pentaxLensDataAttribs
int offsetFirst = 4; // LensInfo2
@@ -766,6 +795,9 @@ Tag::Tag (TagDirectory* p, FILE* f, int base)
offsetFirst = 12; // LensInfo4
else if( strstr(model, "K-01") || strstr(model, "K-30"))
offsetFirst = 15; // LensInfo5
else if(!strncmp(make, "RICOH", 5)) { // all PENTAX camera model produced under the RICOH era uses LensInfo5, for now...
offsetFirst = 15; // LensInfo5 too
}
directory = new TagDirectory*[2];
directory[1] = NULL;
directory[0] = new TagDirectoryTable (parent, f, valuesize,offsetFirst,BYTE , attrib->subdirAttribs, order);
@@ -919,6 +951,14 @@ bool Tag::parseMakerNote(FILE* f, int base, ByteOrder bom )
directory = new TagDirectory*[2];
directory[0] = new TagDirectory (parent, f, base, pentaxAttribs, bom);
directory[1] = NULL;
} else if ( (make.find( "RICOH" ) != std::string::npos ) && (model.find("PENTAX") != std::string::npos) ) {
makerNoteKind = HEADERIFD;
valuesize = 10;
value = new unsigned char[10];
fread (value, 1, 10, f);
directory = new TagDirectory*[2];
directory[0] = new TagDirectory (parent, f, ftell (f)-10, pentaxAttribs, bom);
directory[1] = NULL;
} else if ( make.find( "FUJIFILM" ) != std::string::npos ) {
makerNoteKind = FUJI;
valuesize = 12;
@@ -1050,11 +1090,13 @@ int Tag::toInt (int ofs, TagType astype) {
if (astype == INVALID)
astype = type;
switch (astype) {
//case SBYTE: return (signed char)(value[ofs]);
case SBYTE: return int((reinterpret_cast<signed char*>(value))[ofs]);
case BYTE: return value[ofs];
case ASCII: return 0;
case SSHORT:return (int)int2_to_signed(sget2 (value+ofs, getOrder()));
case SSHORT:return (int)int2_to_signed(sget2 (value+ofs, getOrder()));
case SHORT: return (int)sget2 (value+ofs, getOrder());
case SLONG:
case SLONG:
case LONG: return (int)sget4 (value+ofs, getOrder());
case SRATIONAL:
case RATIONAL: a = (int)sget4 (value+ofs+4, getOrder()); return a==0 ? 0 : (int)sget4 (value+ofs, getOrder()) / a;
@@ -1073,15 +1115,16 @@ double Tag::toDouble (int ofs) {
double ud, dd;
switch (type) {
case SBYTE: return (double)(int((reinterpret_cast<signed char*>(value))[ofs]));
case BYTE: return (double)((int)value[ofs]);
case ASCII: return 0.0;
case SSHORT:return (double)int2_to_signed(sget2 (value+ofs, getOrder()));
case SSHORT:return (double)int2_to_signed(sget2 (value+ofs, getOrder()));
case SHORT: return (double)((int)sget2 (value+ofs, getOrder()));
case SLONG:
case SLONG:
case LONG: return (double)((int)sget4 (value+ofs, getOrder()));
case SRATIONAL:
case SRATIONAL:
case RATIONAL: ud = (int)sget4 (value+ofs, getOrder()); dd = (int)sget4 (value+ofs+4, getOrder()); return dd==0. ? 0. : (double)ud / (double)dd;
case FLOAT:
case FLOAT:
conv.i=sget4 (value+ofs, getOrder());
return conv.f; // IEEE FLOATs are already C format, they just need a recast
@@ -1143,12 +1186,12 @@ void Tag::toString (char* buffer, int ofs) {
return;
}
size_t maxcount = 4;
size_t maxcount = 4;
if (count<4)
maxcount = count;
strcpy (buffer, "");
for (size_t i=0; i<maxcount; i++) {
for (size_t i=0; i<maxcount; i++) {
if (i>0)
strcat (buffer, ", ");
char* b = buffer + strlen(buffer);
@@ -2018,7 +2061,7 @@ std::vector<Tag*> ExifManager::defTags;
// forthis: the byte order will be taken from directory "forthis"
const std::vector<Tag*>& ExifManager::getDefaultTIFFTags (TagDirectory* forthis) {
for (size_t i=0; i<defTags.size(); i++)
for (size_t i=0; i<defTags.size(); i++)
delete defTags[i];
defTags.clear ();
defTags.push_back (new Tag (forthis, lookupAttrib(ifdAttribs,"ImageWidth"), 0, LONG));
@@ -2053,7 +2096,7 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro
TagDirectory* cl;
if (root)
cl = (const_cast<TagDirectory*>(root))->clone (NULL);
cl = (const_cast<TagDirectory*>(root))->clone (NULL);
else
cl = new TagDirectory (NULL, ifdAttribs, INTEL);
@@ -2089,7 +2132,7 @@ int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::pro
TagDirectory* cl;
if (root)
cl = (const_cast<TagDirectory*>(root))->clone (NULL);
cl = (const_cast<TagDirectory*>(root))->clone (NULL);
else
cl = new TagDirectory (NULL, ifdAttribs, INTEL);