112 |
112 |
"Exif.Casio2.ISOSpeed"
|
113 |
113 |
};
|
114 |
114 |
|
|
115 |
struct SensKeyNameList {
|
|
116 |
int count;
|
|
117 |
const char* keys[3];
|
|
118 |
};
|
|
119 |
|
|
120 |
// covers Exif.Phot.SensitivityType values 1-7. Note that SOS, REI and
|
|
121 |
// ISO do differ in their meaning. Values coming first in a list (and
|
|
122 |
// existing as a tag) are picked up first and used as the "ISO" value.
|
|
123 |
static const SensKeyNameList sensitivityKey[] = {
|
|
124 |
{ 1, { "Exif.Photo.StandardOutputSensitivity" }},
|
|
125 |
{ 1, { "Exif.Photo.RecommendedExposureIndex" }},
|
|
126 |
{ 1, { "Exif.Photo.ISOSpeed" }},
|
|
127 |
{ 2, { "Exif.Photo.RecommendedExposureIndex", "Exif.Photo.StandardOutputSensitivity" }},
|
|
128 |
{ 2, { "Exif.Photo.ISOSpeed", "Exif.Photo.StandardOutputSensitivity" }},
|
|
129 |
{ 2, { "Exif.Photo.ISOSpeed", "Exif.Photo.RecommendedExposureIndex" }},
|
|
130 |
{ 3, { "Exif.Photo.ISOSpeed", "Exif.Photo.RecommendedExposureIndex", "Exif.Photo.StandardOutputSensitivity" }}
|
|
131 |
};
|
|
132 |
|
|
133 |
static const char* sensitivityType[] = {
|
|
134 |
"Exif.Photo.SensitivityType"
|
|
135 |
};
|
|
136 |
|
115 |
137 |
// Find the first ISO value which is not "0"
|
116 |
138 |
const int cnt = EXV_COUNTOF(keys);
|
117 |
139 |
ExifData::const_iterator md = ed.end();
|
|
140 |
long iso_val = -1;
|
118 |
141 |
for (int idx = 0; idx < cnt; ) {
|
119 |
142 |
md = findMetadatum(ed, keys + idx, cnt - idx);
|
120 |
143 |
if (md == ed.end()) break;
|
121 |
144 |
std::ostringstream os;
|
122 |
145 |
md->write(os, &ed);
|
123 |
146 |
bool ok = false;
|
124 |
|
long v = parseLong(os.str(), ok);
|
125 |
|
if (ok && v != 0) break;
|
|
147 |
iso_val = parseLong(os.str(), ok);
|
|
148 |
if (ok && iso_val > 0) break;
|
126 |
149 |
while (strcmp(keys[idx++], md->key().c_str()) != 0 && idx < cnt) {}
|
127 |
150 |
md = ed.end();
|
128 |
151 |
}
|
129 |
152 |
|
|
153 |
// there is either a possible ISO "overflow" or no legacy
|
|
154 |
// ISO tag at all. Check for SensitivityType tag and the referenced
|
|
155 |
// ISO value (see EXIF 2.3 Annex G)
|
|
156 |
long iso_tmp_val = -1;
|
|
157 |
while (iso_tmp_val == -1 && (iso_val == 65535 || md == ed.end())) {
|
|
158 |
ExifData::const_iterator md_st = ed.end();
|
|
159 |
md_st = findMetadatum(ed, sensitivityType, 1);
|
|
160 |
// no SensitivityType? exit with existing data
|
|
161 |
if (md_st == ed.end())
|
|
162 |
break;
|
|
163 |
// otherwise pick up actual value and grab value accordingly
|
|
164 |
const char *st_key = 0; // nullptr
|
|
165 |
std::ostringstream os;
|
|
166 |
md_st->write(os, &ed);
|
|
167 |
bool ok = false;
|
|
168 |
long st_val = parseLong(os.str(), ok);
|
|
169 |
// SensivityType out of range or cannot be parsed properly
|
|
170 |
if (!ok || st_val < 1 || st_val > 7)
|
|
171 |
break;
|
|
172 |
// pick up list of ISO tags, and check for at least one of
|
|
173 |
// them available.
|
|
174 |
const SensKeyNameList *sensKeys = &sensitivityKey[st_val - 1];
|
|
175 |
md_st = ed.end();
|
|
176 |
for (int idx = 0; idx < sensKeys->count; md_st = ed.end()) {
|
|
177 |
md_st = findMetadatum(ed, const_cast<const char**>(sensKeys->keys), sensKeys->count);
|
|
178 |
if (md_st == ed.end())
|
|
179 |
break;
|
|
180 |
std::ostringstream os_iso;
|
|
181 |
md_st->write(os_iso, &ed);
|
|
182 |
ok = false;
|
|
183 |
iso_tmp_val = parseLong(os_iso.str(), ok);
|
|
184 |
// something wrong with the value
|
|
185 |
if (ok || iso_tmp_val > 0) {
|
|
186 |
md = md_st;
|
|
187 |
break;
|
|
188 |
}
|
|
189 |
while (strcmp(sensKeys->keys[idx++], md_st->key().c_str()) != 0 && idx < cnt) {}
|
|
190 |
}
|
|
191 |
break;
|
|
192 |
}
|
|
193 |
|
130 |
194 |
return md;
|
131 |
195 |
}
|
132 |
196 |
|
... | ... | |
266 |
330 |
{
|
267 |
331 |
static const char* keys[] = {
|
268 |
332 |
// Exif.Canon.LensModel only reports focal length.
|
269 |
|
// Try Exif.CanonCs.LensType first.
|
|
333 |
// Try Exif.CanonCs.LensType first.
|
270 |
334 |
"Exif.CanonCs.LensType",
|
271 |
335 |
"Exif.Photo.LensModel",
|
272 |
336 |
"Exif.NikonLd1.LensIDNumber",
|