diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index 7ccb5fa6f..82f413c98 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;cr2;crf;crw;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index eba688021..04650472d 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;cr2;crf;crw;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index 4040af7bc..8bda6e11b 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;cr2;crf;crw;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwz;sr2;srw;tif;tiff; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index e60607264..ea2e8b708 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -4894,6 +4894,8 @@ void CLASS parse_kodak_ifd (int base) wbi = -2; } if (tag == 2118) wbtemp = getint(type); + if (tag == 2120 + wbi) /* RT: wb tag for DCS760 */ + FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ if (tag == 2130 + wbi) FORC3 mul[c] = getreal(type); if (tag == 2140 + wbi && wbi >= 0) diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index bb020bc8a..688623980 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ --- dcraw.c 2013-08-12 09:32:14.000000000 +0200 -+++ dcraw.cc 2013-10-22 08:42:39.000000000 +0200 ++++ dcraw.cc 2013-11-03 10:34:08.000000000 +0100 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -671,7 +671,16 @@ float romm_cam[3][3]; fseek (ifp, offset, SEEK_SET); -@@ -5284,8 +4913,8 @@ +@@ -5265,6 +4894,8 @@ + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); ++ if (tag == 2120 + wbi) /* RT: wb tag for DCS760 */ ++ FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) +@@ -5284,8 +4915,8 @@ } } @@ -682,7 +691,7 @@ int CLASS parse_tiff_ifd (int base) { -@@ -5299,7 +4928,7 @@ +@@ -5299,7 +4930,7 @@ unsigned sony_curve[] = { 0,0,0,0,0,4095 }; unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; @@ -691,7 +700,7 @@ if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; -@@ -5737,12 +5366,13 @@ +@@ -5737,12 +5368,13 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -711,7 +720,7 @@ ifp = sfp; free (buf); } -@@ -5766,6 +5396,7 @@ +@@ -5766,6 +5398,7 @@ int CLASS parse_tiff (int base) { int doff; @@ -719,7 +728,7 @@ fseek (ifp, base, SEEK_SET); order = get2(); -@@ -5843,7 +5474,7 @@ +@@ -5843,7 +5476,7 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; @@ -728,7 +737,7 @@ case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && -@@ -5959,7 +5590,7 @@ +@@ -5959,7 +5592,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -737,7 +746,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -5981,13 +5612,14 @@ +@@ -5981,13 +5614,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { @@ -754,7 +763,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -6330,7 +5962,11 @@ +@@ -6330,7 +5964,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -766,7 +775,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6582,7 +6218,8 @@ +@@ -6582,7 +6220,8 @@ { static const struct { const char *prefix; @@ -776,7 +785,7 @@ } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, -@@ -7383,6 +7020,27 @@ +@@ -7383,6 +7022,27 @@ } break; } @@ -804,7 +813,7 @@ } void CLASS simple_coeff (int index) -@@ -7682,13 +7340,20 @@ +@@ -7682,13 +7342,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -827,7 +836,7 @@ parse_ciff (hlen, flen-hlen, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); -@@ -7734,6 +7399,7 @@ +@@ -7734,6 +7401,7 @@ fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); @@ -835,7 +844,7 @@ apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); -@@ -7839,15 +7505,18 @@ +@@ -7839,15 +7507,18 @@ if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); @@ -863,7 +872,7 @@ } for (i=0; i < sizeof corp / sizeof *corp; i++) -@@ -7878,7 +7547,7 @@ +@@ -7878,7 +7549,7 @@ if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ { height = 3124; width = 4688; filters = 0x16161616; } if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) @@ -872,7 +881,7 @@ if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) -@@ -8026,7 +7695,7 @@ +@@ -8026,7 +7697,7 @@ width -= 44; } else if (!strcmp(model,"D3200") || !strcmp(model,"D600") || @@ -881,7 +890,7 @@ width -= 46; } else if (!strcmp(model,"D4")) { width -= 52; -@@ -8630,195 +8299,8 @@ +@@ -8630,195 +8301,8 @@ cmsCloseProfile (hInProfile); } #endif @@ -1079,7 +1088,7 @@ struct tiff_tag { ushort tag, type; -@@ -8841,584 +8323,12 @@ +@@ -8841,584 +8325,12 @@ unsigned gps[26]; char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index c2309f922..ff59bc5d7 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -143,6 +143,26 @@ skip_block: ; int sat = this->get_white(c) - this->get_cblack(c); scale_mul_[c] = (pre_mul_[c] /= dmax) * 65535.0 / sat; } + if (settings->verbose) { + float asn[4] = { 1/cam_mul[0], 1/cam_mul[1], 1/cam_mul[2], 1/cam_mul[3] }; + for (dmax = c = 0; c < 4; c++) { + if (cam_mul[c] == 0) asn[c] = 0; + if (asn[c] > dmax) dmax = asn[c]; + } + for (c = 0; c < 4; c++) asn[c] /= dmax; + printf("cam_mul:[%f %f %f %f], AsShotNeutral:[%f %f %f %f]\n", + cam_mul[0], cam_mul[1], cam_mul[2], cam_mul[3], asn[0], asn[1], asn[2], asn[3]); + printf("pre_mul:[%f %f %f %f], scale_mul:[%f %f %f %f], cblack:[%f %f %f %f]\n", + pre_mul_[0], pre_mul_[1], pre_mul_[2], pre_mul_[3], + scale_mul_[0], scale_mul_[1], scale_mul_[2], scale_mul_[3], + cblack_[0], cblack_[1], cblack_[2], cblack_[3]); + printf("rgb_cam:[ [ %f %f %f], [%f %f %f], [%f %f %f] ]%s\n", + rgb_cam[0][0], rgb_cam[1][1], rgb_cam[2][2], + rgb_cam[0][0], rgb_cam[1][1], rgb_cam[2][2], + rgb_cam[0][0], rgb_cam[1][1], rgb_cam[2][2], + (!this->isBayer()) ? " (not bayer)" : ""); + + } } int RawImage::loadRaw (bool loadData, bool closeFile) @@ -331,9 +351,9 @@ bool RawImage::is_supportedThumb() const { return ( (thumb_width * thumb_height) > 0 && - ( write_thumb == &rtengine::RawImage::jpeg_thumb || - write_thumb == &rtengine::RawImage::ppm_thumb || - thumb_load_raw == &rtengine::RawImage::kodak_thumb_load_raw )); + ( write_thumb == &rtengine::RawImage::jpeg_thumb || + write_thumb == &rtengine::RawImage::ppm_thumb) && + !thumb_load_raw ); } bool diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt index 7e753c3f0..6fa05c032 100644 --- a/rtexif/CMakeLists.txt +++ b/rtexif/CMakeLists.txt @@ -1,5 +1,5 @@ add_library (rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc - pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc) + pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc) IF (WIN32) set_target_properties (rtexif PROPERTIES COMPILE_FLAGS " -ffast-math -fexpensive-optimizations") diff --git a/rtexif/kodakattribs.cc b/rtexif/kodakattribs.cc new file mode 100644 index 000000000..d05f8c4bb --- /dev/null +++ b/rtexif/kodakattribs.cc @@ -0,0 +1,137 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _KODAKATTRIBS_ +#define _KODAKATTRIBS_ + +#include +#include "rtexif.h" + +namespace rtexif { + + +void parseKodakIfdTextualInfo(Tag *textualInfo, Tag* exif_) +{ + // parse TextualInfo and copy values into corresponding standard Exif + if (textualInfo->getType() != ASCII) { + return; + } + TagDirectory *exif = exif_->getDirectory(); + char *value = (char *)textualInfo->getValue(); + int valuesize = textualInfo->getValueSize(); + + char *p = value; + char *pc, *plf; + while ((pc = strchr(p, ':')) != NULL && (plf = strchr(pc, '\n')) != NULL) { + while (*p == ' ') p++; + size_t len = pc - p; + while (len > 1 && p[len-1] == ' ') len--; + std::string key = std::string(p, len); + ++pc; while (*pc == ' ') pc++; + len = plf - pc; + while (len > 1 && pc[len-1] == ' ') len--; + std::string val = std::string(pc, len); + p = ++plf; + + // we pick out a few select tags here + Tag *t; + if (key == "Lens") { + // Proback645 may have "Lens" but not "Focal Length" + float flen = atof(val.c_str()); + if (flen != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational(flen*32, 32); + exif->replaceTag(t); + } + } else if (key == "Focal Length") { + float flen = atof(val.c_str()); + if (flen != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational(flen*32, 32); + exif->replaceTag(t); + } + } else if (key == "Aperture") { + float aperture = atof(&val.c_str()[1]); + if (aperture != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FNumber")); + t->initRational((int)(aperture*10), 10); + exif->replaceTag(t); + } + } else if (key == "Exposure Bias" || key == "Compensation") { + float bias = 0.0; + if (val != "Off") { + bias = atof(val.c_str()); + } + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureBiasValue")); + t->initRational ((int)(bias*1000), 1000); + exif->replaceTag(t); + } else if (key == "ISO Speed") { + t = new Tag (exif, lookupAttrib(exifAttribs,"ISOSpeedRatings")); + t->initInt(atoi(val.c_str()), SHORT); + exif->replaceTag(t); + } else if (key == "Shutter") { + const char *p1 = strchr(val.c_str(), '/'); + int a, b; + if (p1 == NULL) { + a = atoi(val.c_str()); + b = 1; + } else { + a = atoi(val.c_str()); + b = atoi(&p1[1]); + } + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureTime")); + t->initRational(a, b); + exif->replaceTag(t); + + float ssv = -log2((float)a/(float)b); // convert to APEX value + t = new Tag (exif, lookupAttrib(exifAttribs,"ShutterSpeedValue")); + t->initRational(1000000 * ssv, 1000000); + exif->replaceTag(t); + } else if (key == "Flash Fired") { + t = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + if (val == "No") { + t->initInt(0, SHORT); + } else { + // not sure if "Flash Fired" is only yes/no, only seen "No" in test pictures + t->initInt(1, SHORT); + } + exif->replaceTag(t); + } else if (key == "White balance") { // yes should be small 'b' int 'balance'. + t = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + t->initInt((val == "Auto") ? 0 : 1, SHORT); + exif->replaceTag(t); + } + } +} + +// table not complete, not all proprietary Kodak tags are known +const TagAttrib kodakIfdAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "UnknownEV?", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "ExposureValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03e9, AUTO, "OriginalFileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03eb, AUTO, "SensorLeftBorder", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ec, AUTO, "SensorTopBorder", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ed, AUTO, "SensorImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ee, AUTO, "SensorImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03f1, AUTO, "TextualInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03fc, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03fd, AUTO, "Processing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0401, AUTO, "Time", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0414, AUTO, "NCDFileInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0846, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0852, AUTO, "WB_RGBMul0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0853, AUTO, "WB_RGBMul1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0854, AUTO, "WB_RGBMul2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0855, AUTO, "WB_RGBMul3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085c, AUTO, "WB_RGBCoeffs0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085d, AUTO, "WB_RGBCoeffs1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085e, AUTO, "WB_RGBCoeffs2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085f, AUTO, "WB_RGBCoeffs3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0ce5, AUTO, "FirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1391, AUTO, "ToneCurveFileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1784, AUTO, "ISO", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL }}; + +} +#endif + diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index fc55e34d9..7d61ebcab 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -50,7 +50,7 @@ TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* { int numOfTags = get2 (f, order); - if (numOfTags<=0 || numOfTags>200) + if (numOfTags<=0 || numOfTags>1000) // KodakIfd has lots of tags, thus 1000 as the limit return; bool thumbdescr = false; @@ -1238,6 +1238,17 @@ void Tag::initSubDir () { directory[1] = NULL; } +void Tag::initSubDir (TagDirectory* dir) { + type = LONG; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = dir; + directory[1] = NULL; +} + void Tag::initMakerNote (MNKind mnk, const TagAttrib* ta) { type = UNDEFINED; valuesize = 4; @@ -1807,6 +1818,27 @@ TagDirectory* ExifManager::parse (FILE* f, int base, bool skipIgnored) { } } } + if (make && !strncmp((char*)make->getValue(), "Kodak", 5)) { + if (!exif) { + // old Kodak cameras may have exif tags in IFD0, reparse and create an exif subdir + fseek (f, base+firstifd, SEEK_SET); + TagDirectory* exifdir = new TagDirectory (NULL, f, base, exifAttribs, order, true); + + exif = new Tag (root, root->getAttrib ("Exif")); + exif->initSubDir(exifdir); + root->addTagFront (exif); + + if (!exif->getDirectory()->getTag("ISOSpeedRatings") && exif->getDirectory()->getTag ("ExposureIndex")) { + Tag* niso = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + niso->initInt (exif->getDirectory()->getTag ("ExposureIndex")->toInt(), SHORT); + exif->getDirectory()->addTagFront (niso); + } + } + Tag *kodakIFD = root->getTag("KodakIFD"); + if (kodakIFD && kodakIFD->getDirectory()->getTag("TextualInfo")) { + parseKodakIfdTextualInfo(kodakIFD->getDirectory()->getTag("TextualInfo"), exif); + } + } parse_leafdata(root, order); diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 4101d73d5..b50723256 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -82,6 +82,8 @@ struct TagAttrib { Interpreter* interpreter; // Call back hook }; +const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field); + /// A directory of tags class TagDirectory { @@ -173,6 +175,7 @@ class Tag { void initInt (int data, TagType t, int count=1); void initString (const char* text); void initSubDir (); + void initSubDir (TagDirectory* dir); void initMakerNote (MNKind mnk, const TagAttrib* ta); void initUndefArray (const char* data, int len); void initLongArray (const char* data, int len); @@ -216,7 +219,7 @@ class Tag { // get subdirectory (there can be several, the last is NULL) bool isDirectory () { return directory!=NULL; } - TagDirectory* getDirectory (int i=0) { return directory[i]; } + TagDirectory* getDirectory (int i=0) { return (directory) ? directory[i] : 0; } MNKind getMakerNoteFormat () { return makerNoteKind; } }; @@ -449,5 +452,7 @@ extern const TagAttrib sonyCameraSettingsAttribs2[]; extern const TagAttrib sonyCameraSettingsAttribs3[]; //extern const TagAttrib sonyDNGMakerNote[]; extern const TagAttrib olympusAttribs[]; +extern const TagAttrib kodakIfdAttribs[]; +void parseKodakIfdTextualInfo(Tag *textualInfo, Tag* exif); } #endif diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc index dc80c8f06..deb0438d0 100644 --- a/rtexif/stdattribs.cc +++ b/rtexif/stdattribs.cc @@ -371,6 +371,8 @@ public: choices[6] = "Rotate 90 CW"; choices[7] = "Mirror horizontal and rotate 90 CW"; choices[8] = "Rotate 270 CW"; + // '9' is an "unofficial" value for Orientation but used by some older cameras that lacks orientation sensor, such as Kodak DCS + choices[9] = "Unknown"; } }; OrientationInterpreter orientationInterpreter; @@ -420,6 +422,7 @@ const TagAttrib exifAttribs[] = { {0, AC_WRITE, 0, 0, 0x9209, AUTO, "Flash", &flashInterpreter}, {0, AC_WRITE, 0, 0, 0x920A, AUTO, "FocalLength", &focalLengthInterpreter}, {0, AC_WRITE, 0, 0, 0x9214, AUTO, "SubjectArea", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9215, AUTO, "ExposureIndex", &stdInterpreter}, // Note: exists as 0xA215 too, it should be that way {0, AC_DONTWRITE, 0, 0, 0x9216, AUTO, "TIFFEPSStandardID", &stdInterpreter}, {0, AC_WRITE, 0, 0, 0x9217, AUTO, "SensingMethod", &stdInterpreter}, {0, AC_WRITE, 0, 0, 0x927C, AUTO, "MakerNote", &stdInterpreter}, @@ -542,6 +545,7 @@ const TagAttrib iopAttribs[] = { {0, AC_WRITE, 0, 0, 0x4749, AUTO, "RatingPercent",&stdInterpreter}, {0, AC_WRITE, 0, 0, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, {0, AC_WRITE, 0, 0, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, + {0, AC_WRITE, 0, kodakIfdAttribs, 0x8290, AUTO, "KodakIFD", &stdInterpreter}, {0, AC_WRITE, 1, 0, 0x8298, AUTO, "Copyright", &stdInterpreter}, {0, AC_DONTWRITE, 0, 0, 0x8606, AUTO, "LeafData", &stdInterpreter}, // is actually a subdir, but a proprietary format {0, AC_WRITE, 0, exifAttribs, 0x8769, AUTO, "Exif", &stdInterpreter},