Merge branch 'main' into fix_exiv2_-pR
This commit is contained in:
commit
6758e7288d
@ -22,7 +22,9 @@ class Exiv2Conan(ConanFile):
|
||||
|
||||
def requirements(self):
|
||||
self.requires('zlib/1.2.11')
|
||||
self.requires('libcurl/7.75.0')
|
||||
|
||||
if self.options.webready:
|
||||
self.requires('libcurl/7.79.0')
|
||||
|
||||
if os_info.is_windows and self.options.iconv:
|
||||
self.requires('libiconv/1.16')
|
||||
@ -35,7 +37,7 @@ class Exiv2Conan(ConanFile):
|
||||
if self.options.xmp:
|
||||
self.requires('XmpSdk/2016.7@piponazo/stable') # from conan-piponazo
|
||||
else:
|
||||
self.requires('expat/2.3.0')
|
||||
self.requires('expat/2.4.1')
|
||||
|
||||
def imports(self):
|
||||
self.copy('*.dll', dst='bin', src='bin')
|
||||
|
||||
1
doc/templates/Makefile
vendored
1
doc/templates/Makefile
vendored
@ -76,6 +76,7 @@ TABLES = Exif \
|
||||
NikonFl1 \
|
||||
NikonFl2 \
|
||||
NikonFl3 \
|
||||
NikonFl7 \
|
||||
NikonSiD80 \
|
||||
NikonSiD40 \
|
||||
NikonSiD300a \
|
||||
|
||||
5
doc/templates/tags-nikon.html.in
vendored
5
doc/templates/tags-nikon.html.in
vendored
@ -91,6 +91,11 @@ __NikonFl2__
|
||||
__NikonFl3__
|
||||
<br>
|
||||
|
||||
<h3>Nikon Flash Info 7 Tags (for version 0107 and 0108)</h3>
|
||||
<p>Click on a column header to sort the table.</p>
|
||||
__NikonFl7__
|
||||
<br>
|
||||
|
||||
<h3>Nikon Shot Info D80 Tags</h3>
|
||||
<p>Click on a column header to sort the table.</p>
|
||||
__NikonSiD80__
|
||||
|
||||
26
exiv2.md
26
exiv2.md
@ -793,19 +793,19 @@ Image CanonCf Nikon2 NikonPc OlympusFe9 SonyMisc3c
|
||||
Image2 CanonCs Nikon3 NikonPreview OlympusFi SonyMinolta
|
||||
Image3 CanonFi NikonAFT NikonSi01xx OlympusIp SonySInfo1
|
||||
Iop CanonPa NikonAf NikonSi02xx OlympusRd
|
||||
MakerNote CanonPi NikonAf NikonSiD300a OlympusRd2 Samsung2
|
||||
MpfInfo CanonPr NikonAf2 NikonSiD300b OlympusRi SamsungPictureWizard
|
||||
Photo CanonSi NikonAf22 NikonSiD40 SamsungPreview
|
||||
SubImage1 CanonTi NikonCb1 NikonSiD80 Sigma
|
||||
SubImage2 NikonCb2 NikonVr
|
||||
SubImage3 Casio NikonCb2a NikonWt Sony1
|
||||
SubImage4 Casio2 NikonCb2b Sony1Cs
|
||||
SubImage5 NikonCb3 Olympus Sony1Cs2
|
||||
SubImage6 Minolta NikonCb4 Olympus2 Sony1MltCs7D
|
||||
SubImage7 MinoltaCs5D NikonFi OlympusCs Sony1MltCsA100
|
||||
SubImage8 MinoltaCs7D NikonFl1 OlympusEq Sony1MltCsNew
|
||||
SubImage9 MinoltaCsNew NikonFl2 OlympusFe1 Sony1MltCsOld
|
||||
SubThumb1 MinoltaCsOld NikonFl3 OlympusFe2 Sony2
|
||||
MakerNote CanonPi NikonAf2 NikonSiD300a OlympusRd2 Samsung2
|
||||
MpfInfo CanonPr NikonAf22 NikonSiD300b OlympusRi SamsungPictureWizard
|
||||
Photo CanonSi NikonCb1 NikonSiD40 SamsungPreview
|
||||
SubImage1 CanonTi NikonCb2 NikonSiD80 Sigma
|
||||
SubImage2 NikonCb2a NikonVr
|
||||
SubImage3 Casio NikonCb2b NikonWt Sony1
|
||||
SubImage4 Casio2 NikonCb3 Sony1Cs
|
||||
SubImage5 NikonCb4 Olympus Sony1Cs2
|
||||
SubImage6 Minolta NikonFi Olympus2 Sony1MltCs7D
|
||||
SubImage7 MinoltaCs5D NikonFl1 OlympusCs Sony1MltCsA100
|
||||
SubImage8 MinoltaCs7D NikonFl2 OlympusEq Sony1MltCsNew
|
||||
SubImage9 MinoltaCsNew NikonFl3 OlympusFe1 Sony1MltCsOld
|
||||
SubThumb1 MinoltaCsOld NikonFl7 OlympusFe2 Sony2
|
||||
Thumbnail NikonIi OlympusFe3 Sony2Cs
|
||||
Panasonic NikonLd1 OlympusFe4 Sony2Cs2
|
||||
Pentax PanasonicRaw NikonLd2 OlympusFe5 Sony2010e
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "exiv2lib_export.h"
|
||||
|
||||
// included header files
|
||||
#include "error.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
@ -142,6 +143,17 @@ namespace Exiv2 {
|
||||
0 if failure;
|
||||
*/
|
||||
virtual long read(byte* buf, long rcount) = 0;
|
||||
/*!
|
||||
@brief Safe version of `read()` that checks for errors and throws
|
||||
an exception if the read was unsuccessful.
|
||||
@param buf Pointer to a block of memory into which the read data
|
||||
is stored. The memory block must be at least \em rcount bytes
|
||||
long.
|
||||
@param rcount Maximum number of bytes to read. Fewer bytes may be
|
||||
read if \em rcount bytes are not available.
|
||||
@param err Error code to use if an exception is thrown.
|
||||
*/
|
||||
void readOrThrow(byte* buf, long rcount, ErrorCode err);
|
||||
/*!
|
||||
@brief Read one byte from the IO source. Current IO position is
|
||||
advanced by one byte.
|
||||
@ -176,6 +188,19 @@ namespace Exiv2 {
|
||||
#else
|
||||
virtual int seek(long offset, Position pos) = 0;
|
||||
#endif
|
||||
/*!
|
||||
@brief Safe version of `seek()` that checks for errors and throws
|
||||
an exception if the seek was unsuccessful.
|
||||
@param offset Number of bytes to move the position relative
|
||||
to the starting position specified by \em pos
|
||||
@param pos Position from which the seek should start
|
||||
@param err Error code to use if an exception is thrown.
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
void seekOrThrow(int64_t offset, Position pos, ErrorCode err);
|
||||
#else
|
||||
void seekOrThrow(long offset, Position pos, ErrorCode err);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief Direct access to the IO data. For files, this is done by
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "futils.hpp"
|
||||
#include "types.hpp"
|
||||
#include "error.hpp"
|
||||
#include "enforce.hpp"
|
||||
#include "http.hpp"
|
||||
#include "properties.hpp"
|
||||
#include "image_int.hpp"
|
||||
@ -77,6 +78,21 @@ using nlink_t = short;
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) {
|
||||
const long nread = read(buf, rcount);
|
||||
enforce(nread == rcount, err);
|
||||
enforce(!error(), err);
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) {
|
||||
#else
|
||||
void BasicIo::seekOrThrow(long offset, Position pos, ErrorCode err) {
|
||||
#endif
|
||||
const int r = seek(offset, pos);
|
||||
enforce(r == 0, err);
|
||||
}
|
||||
|
||||
//! Internal Pimpl structure of class FileIo.
|
||||
class FileIo::Impl {
|
||||
public:
|
||||
|
||||
@ -138,19 +138,6 @@ namespace {
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
// BasicIo::read() with error checking
|
||||
static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) {
|
||||
const long nread = iIo.read(buf, rcount);
|
||||
enforce(nread == rcount, err);
|
||||
enforce(!iIo.error(), err);
|
||||
}
|
||||
|
||||
// BasicIo::seek() with error checking
|
||||
static void seekOrThrow(BasicIo& iIo, long offset, BasicIo::Position pos, ErrorCode err) {
|
||||
const int r = iIo.seek(offset, pos);
|
||||
enforce(r == 0, err);
|
||||
}
|
||||
|
||||
Image::Image(int imageType, uint16_t supportedMetadata, BasicIo::UniquePtr io)
|
||||
: io_(std::move(io)),
|
||||
pixelWidth_(0),
|
||||
@ -342,8 +329,8 @@ namespace Exiv2 {
|
||||
|
||||
do {
|
||||
// Read top of directory
|
||||
seekOrThrow(io, start, BasicIo::beg, kerCorruptedMetadata);
|
||||
readOrThrow(io, dir.data(), 2, kerCorruptedMetadata);
|
||||
io.seekOrThrow(start, BasicIo::beg, kerCorruptedMetadata);
|
||||
io.readOrThrow(dir.data(), 2, kerCorruptedMetadata);
|
||||
uint16_t dirLength = byteSwap2(dir,0,bSwap);
|
||||
// Prevent infinite loops. (GHSA-m479-7frc-gqqg)
|
||||
enforce(dirLength > 0, kerCorruptedMetadata);
|
||||
@ -369,7 +356,7 @@ namespace Exiv2 {
|
||||
}
|
||||
bFirst = false;
|
||||
|
||||
readOrThrow(io, dir.data(), 12, kerCorruptedMetadata);
|
||||
io.readOrThrow(dir.data(), 12, kerCorruptedMetadata);
|
||||
uint16_t tag = byteSwap2(dir,0,bSwap);
|
||||
uint16_t type = byteSwap2(dir,2,bSwap);
|
||||
uint32_t count = byteSwap4(dir,4,bSwap);
|
||||
@ -420,9 +407,9 @@ namespace Exiv2 {
|
||||
|
||||
if ( bOffsetIsPointer ) { // read into buffer
|
||||
const long restore = io.tell(); // save
|
||||
seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
readOrThrow(io, buf.data(), static_cast<long>(count_x_size), kerCorruptedMetadata); // read
|
||||
seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
io.seekOrThrow(offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
io.readOrThrow(buf.data(), static_cast<long>(count_x_size), kerCorruptedMetadata); // read
|
||||
io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
}
|
||||
|
||||
if ( bPrint ) {
|
||||
@ -464,7 +451,7 @@ namespace Exiv2 {
|
||||
const long restore = io.tell();
|
||||
offset = byteSwap4(buf,k*size,bSwap);
|
||||
printIFDStructure(io,out,option,offset,bSwap,c,depth);
|
||||
seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
}
|
||||
} else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {
|
||||
if (count > 0) {
|
||||
@ -473,11 +460,11 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
const long restore = io.tell();
|
||||
seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
io.seekOrThrow(offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
std::vector<byte> bytes(count) ; // allocate memory
|
||||
// TODO: once we have C++11 use bytes.data()
|
||||
readOrThrow(io, &bytes[0], count, kerCorruptedMetadata);
|
||||
seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
io.readOrThrow(&bytes[0], count, kerCorruptedMetadata);
|
||||
io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
// TODO: once we have C++11 use bytes.data()
|
||||
IptcData::printStructure(out, makeSliceUntil(&bytes[0], count), depth);
|
||||
}
|
||||
@ -487,8 +474,8 @@ namespace Exiv2 {
|
||||
uint32_t jump= 10 ;
|
||||
byte bytes[20] ;
|
||||
const auto chars = reinterpret_cast<const char*>(&bytes[0]);
|
||||
seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
readOrThrow(io, bytes, jump, kerCorruptedMetadata) ; // read
|
||||
io.seekOrThrow(offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
io.readOrThrow(bytes, jump, kerCorruptedMetadata) ; // read
|
||||
bytes[jump]=0 ;
|
||||
|
||||
bool bNikon = ::strcmp("Nikon" ,chars) == 0;
|
||||
@ -498,17 +485,17 @@ namespace Exiv2 {
|
||||
// tag is an embedded tiff
|
||||
const long byteslen = count-jump;
|
||||
DataBuf bytes(byteslen); // allocate a buffer
|
||||
readOrThrow(io, bytes.data(), byteslen, kerCorruptedMetadata); // read
|
||||
io.readOrThrow(bytes.data(), byteslen, kerCorruptedMetadata); // read
|
||||
MemIo memIo(bytes.c_data(), byteslen) ; // create a file
|
||||
printTiffStructure(memIo,out,option,depth);
|
||||
} else {
|
||||
// tag is an IFD
|
||||
uint32_t punt = bSony ? 12 : 0 ;
|
||||
seekOrThrow(io, 0, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
io.seekOrThrow(0, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
printIFDStructure(io,out,option,offset+punt,bSwap,c,depth);
|
||||
}
|
||||
|
||||
seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
io.seekOrThrow(restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +508,7 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
if ( start ) {
|
||||
readOrThrow(io, dir.data(), 4, kerCorruptedMetadata);
|
||||
io.readOrThrow(dir.data(), 4, kerCorruptedMetadata);
|
||||
start = byteSwap4(dir,0,bSwap);
|
||||
}
|
||||
} while (start) ;
|
||||
@ -541,7 +528,7 @@ namespace Exiv2 {
|
||||
DataBuf dir(dirSize);
|
||||
|
||||
// read header (we already know for certain that we have a Tiff file)
|
||||
readOrThrow(io, dir.data(), 8, kerCorruptedMetadata);
|
||||
io.readOrThrow(dir.data(), 8, kerCorruptedMetadata);
|
||||
char c = static_cast<char>(dir.read_uint8(0));
|
||||
bool bSwap = ( c == 'M' && isLittleEndianPlatform() )
|
||||
|| ( c == 'I' && isBigEndianPlatform() )
|
||||
|
||||
@ -94,19 +94,6 @@ namespace Exiv2 {
|
||||
constexpr uint16_t Photoshop::iptc_ = 0x0404;
|
||||
constexpr uint16_t Photoshop::preview_ = 0x040c;
|
||||
|
||||
// BasicIo::read() with error checking
|
||||
static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) {
|
||||
const long nread = iIo.read(buf, rcount);
|
||||
enforce(nread == rcount, err);
|
||||
enforce(!iIo.error(), err);
|
||||
}
|
||||
|
||||
// BasicIo::seek() with error checking
|
||||
static void seekOrThrow(BasicIo& iIo, long offset, BasicIo::Position pos, ErrorCode err) {
|
||||
const int r = iIo.seek(offset, pos);
|
||||
enforce(r == 0, err);
|
||||
}
|
||||
|
||||
static inline bool inRange(int lo,int value, int hi)
|
||||
{
|
||||
return lo<=value && value <= hi;
|
||||
@ -389,7 +376,7 @@ namespace Exiv2 {
|
||||
byte sizebuf[2];
|
||||
uint16_t size = 0;
|
||||
if (markerHasLength(marker)) {
|
||||
readOrThrow(*io_, sizebuf, 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
|
||||
size = getUShort(sizebuf, bigEndian);
|
||||
// `size` is the size of the segment, including the 2-byte size field
|
||||
// that we just read.
|
||||
@ -399,7 +386,7 @@ namespace Exiv2 {
|
||||
// Read the rest of the segment.
|
||||
DataBuf buf(size);
|
||||
if (size > 0) {
|
||||
readOrThrow(*io_, buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
buf.copyBytes(0, sizebuf, 2);
|
||||
}
|
||||
|
||||
@ -616,7 +603,7 @@ namespace Exiv2 {
|
||||
byte sizebuf[2];
|
||||
uint16_t size = 0;
|
||||
if (markerHasLength(marker)) {
|
||||
readOrThrow(*io_, sizebuf, 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
|
||||
size = getUShort(sizebuf, bigEndian);
|
||||
// `size` is the size of the segment, including the 2-byte size field
|
||||
// that we just read.
|
||||
@ -627,7 +614,7 @@ namespace Exiv2 {
|
||||
DataBuf buf(size);
|
||||
if (size > 0) {
|
||||
assert(size >= 2); // enforced above
|
||||
readOrThrow(*io_, buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
buf.copyBytes(0, sizebuf, 2);
|
||||
}
|
||||
|
||||
@ -847,16 +834,16 @@ namespace Exiv2 {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << start << ":" << length << std::endl;
|
||||
#endif
|
||||
seekOrThrow(*io_, start, BasicIo::beg, kerFailedToReadImageData);
|
||||
io_->seekOrThrow(start, BasicIo::beg, kerFailedToReadImageData);
|
||||
DataBuf buf(length);
|
||||
readOrThrow(*io_, buf.data(), buf.size(), kerFailedToReadImageData);
|
||||
io_->readOrThrow(buf.data(), buf.size(), kerFailedToReadImageData);
|
||||
tempIo->write(buf.c_data(), buf.size());
|
||||
}
|
||||
}
|
||||
|
||||
seekOrThrow(*io_, 0, BasicIo::beg, kerFailedToReadImageData);
|
||||
io_->seekOrThrow(0, BasicIo::beg, kerFailedToReadImageData);
|
||||
io_->transfer(*tempIo); // may throw
|
||||
seekOrThrow(*io_, 0, BasicIo::beg, kerFailedToReadImageData);
|
||||
io_->seekOrThrow(0, BasicIo::beg, kerFailedToReadImageData);
|
||||
readMetadata();
|
||||
}
|
||||
} // JpegBase::printStructure
|
||||
@ -923,7 +910,7 @@ namespace Exiv2 {
|
||||
byte sizebuf[2];
|
||||
uint16_t size = 0;
|
||||
if (markerHasLength(marker)) {
|
||||
readOrThrow(*io_, sizebuf, 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
|
||||
size = getUShort(sizebuf, bigEndian);
|
||||
// `size` is the size of the segment, including the 2-byte size field
|
||||
// that we just read.
|
||||
@ -934,7 +921,7 @@ namespace Exiv2 {
|
||||
DataBuf buf(size);
|
||||
if (size > 0) {
|
||||
assert(size >= 2); // enforced above
|
||||
readOrThrow(*io_, buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
buf.copyBytes(0, sizebuf, 2);
|
||||
}
|
||||
|
||||
@ -1024,7 +1011,7 @@ namespace Exiv2 {
|
||||
if (!comment_.empty())
|
||||
++search;
|
||||
|
||||
seekOrThrow(*io_, seek, BasicIo::beg, kerNoImageInInputData);
|
||||
io_->seekOrThrow(seek, BasicIo::beg, kerNoImageInInputData);
|
||||
count = 0;
|
||||
marker = advanceToMarker(kerNoImageInInputData);
|
||||
|
||||
@ -1037,7 +1024,7 @@ namespace Exiv2 {
|
||||
byte sizebuf[2];
|
||||
uint16_t size = 0;
|
||||
if (markerHasLength(marker)) {
|
||||
readOrThrow(*io_, sizebuf, 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(sizebuf, 2, kerFailedToReadImageData);
|
||||
size = getUShort(sizebuf, bigEndian);
|
||||
// `size` is the size of the segment, including the 2-byte size field
|
||||
// that we just read.
|
||||
@ -1048,7 +1035,7 @@ namespace Exiv2 {
|
||||
DataBuf buf(size);
|
||||
if (size > 0) {
|
||||
assert(size >= 2); // enforced above
|
||||
readOrThrow(*io_, buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
io_->readOrThrow(buf.data(2), size - 2, kerFailedToReadImageData);
|
||||
buf.copyBytes(0, sizebuf, 2);
|
||||
}
|
||||
|
||||
|
||||
@ -1139,6 +1139,10 @@ namespace Exiv2 {
|
||||
{ 0x00a8, "0101", 0, 0, NA },
|
||||
{ 0x00a8, "0102", 0, 1, NA },
|
||||
{ 0x00a8, "0103", 0, 2, NA },
|
||||
{ 0x00a8, "0104", 0, 2, NA },
|
||||
{ 0x00a8, "0105", 0, 2, NA },
|
||||
{ 0x00a8, "0107", 0, 3, NA },
|
||||
{ 0x00a8, "0108", 0, 3, NA },
|
||||
};
|
||||
|
||||
int nikonSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const /*pRoot*/)
|
||||
|
||||
@ -38,6 +38,8 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <math.h> //for log, pow, abs
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
@ -1050,7 +1052,6 @@ namespace Exiv2 {
|
||||
{ 5, N_("GN (distance priority)") },
|
||||
{ 6, N_("Manual") },
|
||||
{ 7, N_("Repeating Flash") },
|
||||
{ 7, N_("Repeating Flash") } // To silence compiler warning
|
||||
};
|
||||
|
||||
//! ExternalFlashFlags
|
||||
@ -1135,6 +1136,32 @@ namespace Exiv2 {
|
||||
return tagInfoFl3_;
|
||||
}
|
||||
|
||||
// Nikon3 Flash Info 7 (0107 and 0108) Tag Info
|
||||
constexpr TagInfo Nikon3MakerNote::tagInfoFl7_[] = {
|
||||
{ 0, "Version", N_("Version"), N_("Flash info version"), nikonFl7Id, makerTags, undefined, 4, printExifVersion},
|
||||
{ 4, "FlashSource", N_("Flash source"), N_("The type of flash used (if any)"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashSource)},
|
||||
{ 6, "ExternalFlashFirmware", N_("External Flash Firmware"), N_("External flash firmware version"), nikonFl7Id, makerTags, unsignedShort, 1, EXV_PRINT_TAG(nikonFlashFirmware)},
|
||||
{ 8, "ExternalFlashData1", N_("External flash data"), N_("External flash data"), nikonFl7Id, makerTags, unsignedByte, 1, printExternalFlashData1},
|
||||
{ 9, "ExternalFlashData2", N_("External flash ready state"), N_("External flash ready state"), nikonFl7Id, makerTags, unsignedByte, 1, printExternalFlashData2},
|
||||
{ 10, "FlashCompensation", N_("Flash compensation"), N_("Flash compensation"), nikonFl7Id, makerTags, signedByte, 1, printFlashCompensation},
|
||||
{ 12, "FlashFocalLength", N_("Flash focal length"), N_("Flash focal length"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashFocalLength},
|
||||
{ 13, "RepeatingFlashRate", N_("Repeating flash rate"), N_("Repeating flash rate"), nikonFl7Id, makerTags, unsignedByte, 1, printRepeatingFlashRate},
|
||||
{ 14, "RepeatingFlashCount", N_("Repeating flash count"), N_("Repeating flash count"), nikonFl7Id, makerTags, unsignedByte, 1, printRepeatingFlashCount},
|
||||
{ 15, "FlashGNDistance", N_("Flash GN Distance"), N_("Flash GN distance"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashGNDistance)},
|
||||
{ 17, "FlashGroupAControlData", N_("Flash group A control data"), N_("Flash group A control data"), nikonFl7Id, makerTags, unsignedByte, 1, EXV_PRINT_TAG(nikonFlashControlMode)},
|
||||
{ 18, "FlashGroupBCControlData", N_("Flash group B/C control data"), N_("Flash group B/C control data"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupBCControlData},
|
||||
{ 40, "FlashGroupAData", N_("Flash group A data"), N_("Depending upon FlashGroupAControlData, either the FlashGroupACompensation value or the FlashGroupAOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupAData},
|
||||
{ 41, "FlashGroupBData", N_("Flash group B data"), N_("Depending upon FlashGroupBCControlData, either the FlashGroupBCompensation value or the FlashGroupBOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupBData},
|
||||
{ 42, "FlashGroupCData", N_("Flash group C data"), N_("Depending upon FlashGroupBCControlData, either the FlashGroupCCompensation value or the FlashGroupCOutput value"), nikonFl7Id, makerTags, unsignedByte, 1, printFlashGroupCData},
|
||||
// End of list marker
|
||||
{0xffff, "(UnknownNikonFl7Tag)", "(UnknownNikonFl7Tag)", N_("Unknown Nikon Flash Info 7 Tag"), nikonFl7Id, makerTags, unsignedByte, 1, printValue},
|
||||
};
|
||||
|
||||
const TagInfo* Nikon3MakerNote::tagListFl7()
|
||||
{
|
||||
return tagInfoFl7_;
|
||||
}
|
||||
|
||||
// Nikon3 Shot Info D80 Tag Info
|
||||
constexpr TagInfo Nikon3MakerNote::tagInfoSi1_[] = {
|
||||
{ 0, "Version", N_("Version"), N_("Version"), nikonSi1Id, makerTags, unsignedByte, 4, printExifVersion},
|
||||
@ -2772,14 +2799,18 @@ fmountlens[] = {
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) {
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
auto temp = value.toLong();
|
||||
if (temp == 0 || temp == 255)
|
||||
return os << _("n/a");
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
os << std::fixed << std::setprecision(1) << value.toLong() << " mm";
|
||||
os << std::fixed << std::setprecision(1) << temp << " mm";
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
@ -2790,12 +2821,16 @@ fmountlens[] = {
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) {
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
return os << "(" << value << ")";
|
||||
}
|
||||
auto temp = value.toLong();
|
||||
if (temp == 0 || temp == 255)
|
||||
return os << _("n/a");
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
os << std::fixed << std::setprecision(2) << value.toLong() << " Hz";
|
||||
os << std::fixed << std::setprecision(2) << temp << " Hz";
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
@ -2806,12 +2841,250 @@ fmountlens[] = {
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte || value.toLong() == 0 || value.toLong() == 255) {
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
return os << "(" << value << ")";
|
||||
}
|
||||
auto temp = value.toLong();
|
||||
if (temp == 0 || temp == 255)
|
||||
return os << _("n/a");
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
os << std::fixed << std::setprecision(2) << temp;
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printExternalFlashData1(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
os << std::fixed << std::setprecision(2) << value.toLong();
|
||||
os << (value.toLong() & 0x80 ? _("External flash zoom override") : _("No external flash zoom override"));
|
||||
os << ", ";
|
||||
os << (value.toLong() & 0x01 ? _("external flash attached") : _("external flash not attached"));
|
||||
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printExternalFlashData2(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
long temp = value.toLong();
|
||||
|
||||
switch (temp & 0x07) {
|
||||
case 0:
|
||||
os << _("n/a");
|
||||
break;
|
||||
case 1:
|
||||
os << _("Ready");
|
||||
break;
|
||||
case 6:
|
||||
os << _("Not ready");
|
||||
break;
|
||||
default:
|
||||
os << "(" << temp << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printFlashCompensation(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != signedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
float temp = ( value.toFloat()/float(-6.0) );
|
||||
|
||||
if (temp == 0)
|
||||
os << 0;
|
||||
else if (!std::isfinite(temp))
|
||||
os << "(" << value << ")";
|
||||
else if (std::abs(std::remainderf(temp, 1)) < 0.001)
|
||||
os << std::round(temp);
|
||||
else if (std::abs(std::remainderf(temp*2, 1)) < 0.001)
|
||||
os << std::round(temp*2) << "/2";
|
||||
else if (std::abs(std::remainderf(temp*3, 1)) < 0.001)
|
||||
os << std::round(temp*3) << "/3";
|
||||
else
|
||||
os << std::setprecision(3) << temp;
|
||||
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printFlashGroupBCControlData(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData* data)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
long temp = value.toLong();
|
||||
|
||||
printTag<EXV_COUNTOF(nikonFlashControlMode), nikonFlashControlMode>(os, (temp >> 4), data);
|
||||
os << ", ";
|
||||
printTag<EXV_COUNTOF(nikonFlashControlMode), nikonFlashControlMode>(os, (temp & 0x0f), data);
|
||||
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printFlashGroupAData(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData* metadata)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
double temp = value.toFloat()/double(-6.0);
|
||||
|
||||
auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupAControlData"));
|
||||
if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
}
|
||||
else {
|
||||
if (pos->toLong() < 0x06) {
|
||||
// FlashGroupACompensation value
|
||||
if (temp == 0)
|
||||
os << 0;
|
||||
else
|
||||
os << std::fixed << std::setprecision(1) << temp;
|
||||
}
|
||||
else {
|
||||
// FlashGroupAOutput value
|
||||
double flashGroupAOutput = std::exp2(temp);
|
||||
if (flashGroupAOutput > 0.99)
|
||||
os << _("Full");
|
||||
else
|
||||
os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%";
|
||||
}
|
||||
}
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printFlashGroupBData(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData* metadata)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
double temp = value.toFloat()/double(-6.0);
|
||||
|
||||
auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupBCControlData"));
|
||||
if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
}
|
||||
else {
|
||||
if (pos->toLong() < 0x06) {
|
||||
// FlashGroupBCompensation value
|
||||
if (temp == 0)
|
||||
os << 0;
|
||||
else
|
||||
os << std::fixed << std::setprecision(1) << temp;
|
||||
}
|
||||
else {
|
||||
// FlashGroupBOutput value
|
||||
double flashGroupAOutput = std::exp2(temp);
|
||||
if (flashGroupAOutput > 0.99)
|
||||
os << _("Full");
|
||||
else
|
||||
os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%";
|
||||
}
|
||||
}
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& Nikon3MakerNote::printFlashGroupCData(std::ostream& os,
|
||||
const Value& value,
|
||||
const ExifData* metadata)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.copyfmt(os);
|
||||
double temp = value.toFloat()/double(-6.0);
|
||||
|
||||
auto pos = metadata->findKey(ExifKey("Exif.NikonFl7.FlashGroupBCControlData"));
|
||||
if (pos == metadata->end() || pos-> count() != 1 || pos->typeId() != unsignedByte) {
|
||||
os << "(" << value << ")";
|
||||
}
|
||||
else {
|
||||
if (pos->toLong() < 0x06) {
|
||||
// FlashGroupCCompensation value
|
||||
if (temp == 0)
|
||||
os << 0;
|
||||
else
|
||||
os << std::fixed << std::setprecision(1) << temp;
|
||||
}
|
||||
else {
|
||||
// FlashGroupCOutput value
|
||||
double flashGroupAOutput = std::exp2(temp);
|
||||
if (flashGroupAOutput > 0.99)
|
||||
os << _("Full");
|
||||
else
|
||||
os << std::setprecision(2) << std::round(flashGroupAOutput*100) << "%";
|
||||
}
|
||||
}
|
||||
os.copyfmt(oss);
|
||||
os.flags(f);
|
||||
return os;
|
||||
|
||||
@ -130,6 +130,8 @@ namespace Exiv2 {
|
||||
static const TagInfo* tagListFl2();
|
||||
//! Return read-only list of built-in Flash Info 3 tags
|
||||
static const TagInfo* tagListFl3();
|
||||
//! Return read-only list of built-in Flash Info 7 (0107 and 0108) tags
|
||||
static const TagInfo* tagListFl7();
|
||||
//! Return read-only list of built-in Shot Info D80 tags
|
||||
static const TagInfo* tagListSi1();
|
||||
//! Return read-only list of built-in Shot Info D40 tags
|
||||
@ -217,6 +219,20 @@ namespace Exiv2 {
|
||||
static std::ostream& printRepeatingFlashRate(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print repeating flash count
|
||||
static std::ostream& printRepeatingFlashCount(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print external flash data 1 value
|
||||
static std::ostream& printExternalFlashData1(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print external flash data 2 value
|
||||
static std::ostream& printExternalFlashData2(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print flash compensation value
|
||||
static std::ostream& printFlashCompensation(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print flash group B/C control data value
|
||||
static std::ostream& printFlashGroupBCControlData(std::ostream& os, const Value& value, const ExifData* data);
|
||||
//! Print flash group A data value
|
||||
static std::ostream& printFlashGroupAData(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print flash group B data value
|
||||
static std::ostream& printFlashGroupBData(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print flash group C data value
|
||||
static std::ostream& printFlashGroupCData(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print time zone
|
||||
static std::ostream& printTimeZone(std::ostream& os, const Value& value, const ExifData*);
|
||||
//! Print picture control value
|
||||
@ -252,6 +268,8 @@ namespace Exiv2 {
|
||||
static const TagInfo tagInfoFl2_[];
|
||||
//! Flash Info 3 tag information
|
||||
static const TagInfo tagInfoFl3_[];
|
||||
//! Flash Info 7 (0107 and 0108) tag information
|
||||
static const TagInfo tagInfoFl7_[];
|
||||
//! Shot Info D80 tag information
|
||||
static const TagInfo tagInfoSi1_[];
|
||||
//! Shot Info D40 tag information
|
||||
|
||||
@ -115,6 +115,7 @@ namespace Exiv2 {
|
||||
{ nikonFl1Id, "Makernote", "NikonFl1", Nikon3MakerNote::tagListFl1 },
|
||||
{ nikonFl2Id, "Makernote", "NikonFl2", Nikon3MakerNote::tagListFl2 },
|
||||
{ nikonFl3Id, "Makernote", "NikonFl3", Nikon3MakerNote::tagListFl3 },
|
||||
{ nikonFl7Id, "Makernote", "NikonFl7", Nikon3MakerNote::tagListFl7 },
|
||||
{ nikonSi1Id, "Makernote", "NikonSiD80", Nikon3MakerNote::tagListSi1 },
|
||||
{ nikonSi2Id, "Makernote", "NikonSiD40", Nikon3MakerNote::tagListSi2 },
|
||||
{ nikonSi3Id, "Makernote", "NikonSiD300a", Nikon3MakerNote::tagListSi3 },
|
||||
|
||||
@ -125,6 +125,7 @@ namespace Exiv2 {
|
||||
nikonFl1Id,
|
||||
nikonFl2Id,
|
||||
nikonFl3Id,
|
||||
nikonFl7Id,
|
||||
nikonSi1Id,
|
||||
nikonSi2Id,
|
||||
nikonSi3Id,
|
||||
@ -266,9 +267,9 @@ namespace Exiv2 {
|
||||
by looking up a reference table.
|
||||
*/
|
||||
template <int N, const TagDetails (&array)[N]>
|
||||
std::ostream& printTag(std::ostream& os, const Value& value, const ExifData*)
|
||||
std::ostream& printTag(std::ostream& os, const long& value, const ExifData*)
|
||||
{
|
||||
const TagDetails* td = find(array, value.toLong());
|
||||
const TagDetails* td = find(array, value);
|
||||
if (td) {
|
||||
os << exvGettext(td->label_);
|
||||
}
|
||||
@ -278,7 +279,17 @@ namespace Exiv2 {
|
||||
return os;
|
||||
}
|
||||
|
||||
//! Shortcut for the printTag template which requires typing the array name only once.
|
||||
/*!
|
||||
@brief Generic pretty-print function to translate the first long value in Value, to a description
|
||||
by looking up a reference table.
|
||||
*/
|
||||
template <int N, const TagDetails (&array)[N]>
|
||||
std::ostream& printTag(std::ostream& os, const Value& value, const ExifData* data)
|
||||
{
|
||||
return printTag<N, array>(os, value.toLong(), data);
|
||||
}
|
||||
|
||||
//! Shortcut for the printTag template which requires typing the array name only once.
|
||||
#define EXV_PRINT_TAG(array) printTag<EXV_COUNTOF(array), array>
|
||||
|
||||
/*!
|
||||
|
||||
@ -427,11 +427,42 @@ namespace Exiv2 {
|
||||
{ 15, ttUnsignedByte, 1 }, // FlashGNDistance
|
||||
{ 16, ttUnsignedByte, 1 }, // FlashColorFilter
|
||||
};
|
||||
//! Nikon Lens Data configurations and definitions
|
||||
//! Nikon Flash Info 7 (0107 and 0108) binary array - configuration
|
||||
constexpr ArrayCfg nikonFl7Cfg = {
|
||||
nikonFl7Id, // Group for the elements
|
||||
bigEndian, // Use byte order from parent
|
||||
ttUndefined, // Type for array entry
|
||||
notEncrypted, // Not encrypted
|
||||
false, // No size element
|
||||
true, // Write all tags
|
||||
true, // Concatenate gaps
|
||||
{ 0, ttUnsignedByte, 1 }
|
||||
};
|
||||
//! Nikon Flash Info 7 (0107 and 0108) binary array - definition
|
||||
constexpr ArrayDef nikonFl7Def[] = {
|
||||
{ 0, ttUndefined, 4 }, // Version
|
||||
{ 4, ttUnsignedByte, 1 }, // FlashSource
|
||||
{ 6, ttUnsignedShort, 1 }, // ExternalFlashFirmware
|
||||
{ 8, ttUnsignedByte, 1 }, // ExternalFlashData1
|
||||
{ 9, ttUnsignedByte, 1 }, // ExternalFlashData2
|
||||
{ 10, ttSignedByte, 1 }, // FlashCompensation
|
||||
{ 12, ttUnsignedByte, 1 }, // FlashFocalLength
|
||||
{ 13, ttUnsignedByte, 1 }, // RepeatingFlashRate
|
||||
{ 14, ttUnsignedByte, 1 }, // RepeatingFlashCount
|
||||
{ 15, ttUnsignedByte, 1 }, // FlashGNDistance
|
||||
{ 17, ttUnsignedByte, 1 }, // FlashGroupAControlData
|
||||
{ 18, ttUnsignedByte, 1 }, // FlashGroupBCControlData
|
||||
{ 40, ttUnsignedByte, 1 }, // FlashGroupAData
|
||||
{ 41, ttUnsignedByte, 1 }, // FlashGroupBData
|
||||
{ 42, ttUnsignedByte, 1 } // FlashGroupCData
|
||||
};
|
||||
|
||||
//! Nikon Flash Info Data configurations and definitions
|
||||
constexpr ArraySet nikonFlSet[] = {
|
||||
{ nikonFl1Cfg, nikonFl1Def, EXV_COUNTOF(nikonFl1Def) },
|
||||
{ nikonFl2Cfg, nikonFl2Def, EXV_COUNTOF(nikonFl2Def) },
|
||||
{ nikonFl3Cfg, nikonFl3Def, EXV_COUNTOF(nikonFl3Def) }
|
||||
{ nikonFl3Cfg, nikonFl3Def, EXV_COUNTOF(nikonFl3Def) },
|
||||
{ nikonFl7Cfg, nikonFl7Def, EXV_COUNTOF(nikonFl7Def) }
|
||||
};
|
||||
|
||||
//! Nikon Shot Info binary array - configuration 1 (D80)
|
||||
@ -1177,6 +1208,7 @@ namespace Exiv2 {
|
||||
{ Tag::root, nikonFl1Id, nikon3Id, 0x00a8 },
|
||||
{ Tag::root, nikonFl2Id, nikon3Id, 0x00a8 },
|
||||
{ Tag::root, nikonFl3Id, nikon3Id, 0x00a8 },
|
||||
{ Tag::root, nikonFl7Id, nikon3Id, 0x00a8 },
|
||||
{ Tag::root, panasonicId, exifId, 0x927c },
|
||||
{ Tag::root, pentaxId, exifId, 0x927c },
|
||||
{ Tag::root, pentaxDngId, ifd0Id, 0xc634 },
|
||||
@ -1577,6 +1609,7 @@ namespace Exiv2 {
|
||||
{ Tag::all, nikonFl1Id, newTiffBinaryElement },
|
||||
{ Tag::all, nikonFl2Id, newTiffBinaryElement },
|
||||
{ Tag::all, nikonFl3Id, newTiffBinaryElement },
|
||||
{ Tag::all, nikonFl7Id, newTiffBinaryElement },
|
||||
|
||||
// Nikon3 shot info
|
||||
{ Tag::all, nikonSi1Id, newTiffBinaryElement },
|
||||
|
||||
@ -55,14 +55,6 @@
|
||||
namespace Exiv2 {
|
||||
using namespace Exiv2::Internal;
|
||||
|
||||
// This static function is a temporary fix in v0.27. In the next version,
|
||||
// it will be added as a method of BasicIo.
|
||||
static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) {
|
||||
const long nread = iIo.read(buf, rcount);
|
||||
enforce(nread == rcount, err);
|
||||
enforce(!iIo.error(), err);
|
||||
}
|
||||
|
||||
WebPImage::WebPImage(BasicIo::UniquePtr io)
|
||||
: Image(ImageType::webp, mdNone, std::move(io))
|
||||
{
|
||||
@ -140,7 +132,7 @@ namespace Exiv2 {
|
||||
DataBuf chunkId(WEBP_TAG_SIZE+1);
|
||||
chunkId.write_uint8(WEBP_TAG_SIZE, '\0');
|
||||
|
||||
readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
uint64_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian);
|
||||
|
||||
/* Set up header */
|
||||
@ -180,8 +172,8 @@ namespace Exiv2 {
|
||||
case we have any exif or xmp data, also check
|
||||
for any chunks with alpha frame/layer set */
|
||||
while (!io_->eof() && static_cast<uint64_t>(io_->tell()) < filesize) {
|
||||
readOrThrow(*io_, chunkId.data(), WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
|
||||
|
||||
// Check that `size_u32` is safe to cast to `long`.
|
||||
@ -189,10 +181,10 @@ namespace Exiv2 {
|
||||
Exiv2::kerCorruptedMetadata);
|
||||
const long size = static_cast<long>(size_u32);
|
||||
DataBuf payload(size);
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
if ( payload.size() % 2 ) {
|
||||
byte c = 0;
|
||||
readOrThrow(*io_, &c, 1, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(&c, 1, Exiv2::kerCorruptedMetadata);
|
||||
}
|
||||
|
||||
/* Chunk with information about features
|
||||
@ -317,8 +309,8 @@ namespace Exiv2 {
|
||||
|
||||
io_->seek(12, BasicIo::beg);
|
||||
while (!io_->eof() && static_cast<uint64_t>(io_->tell()) < filesize) {
|
||||
readOrThrow(*io_, chunkId.data(), 4, Exiv2::kerCorruptedMetadata);
|
||||
readOrThrow(*io_, size_buff, 4, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(chunkId.data(), 4, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(size_buff, 4, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
|
||||
|
||||
@ -328,7 +320,7 @@ namespace Exiv2 {
|
||||
const long size = static_cast<long>(size_u32);
|
||||
|
||||
DataBuf payload(size);
|
||||
readOrThrow(*io_, payload.data(), size, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), size, Exiv2::kerCorruptedMetadata);
|
||||
if ( io_->tell() % 2 ) io_->seek(+1,BasicIo::cur); // skip pad
|
||||
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X)) {
|
||||
@ -520,7 +512,7 @@ namespace Exiv2 {
|
||||
DataBuf chunkId(5);
|
||||
chunkId.write_uint8(4, '\0');
|
||||
|
||||
readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
const uint32_t filesize_u32 =
|
||||
Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
|
||||
@ -546,8 +538,8 @@ namespace Exiv2 {
|
||||
|
||||
chunkId.write_uint8(4, '\0');
|
||||
while (!io_->eof() && io_->tell() < filesize) {
|
||||
readOrThrow(*io_, chunkId.data(), WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
|
||||
|
||||
@ -568,7 +560,7 @@ namespace Exiv2 {
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf, payload.c_data(4), 3);
|
||||
@ -583,7 +575,7 @@ namespace Exiv2 {
|
||||
enforce(size >= 10, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
// Fetch width""
|
||||
@ -604,7 +596,7 @@ namespace Exiv2 {
|
||||
byte size_buf_w[2];
|
||||
byte size_buf_h[3];
|
||||
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf_w, payload.c_data(1), 2);
|
||||
@ -622,7 +614,7 @@ namespace Exiv2 {
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf, payload.c_data(6), 3);
|
||||
@ -634,10 +626,10 @@ namespace Exiv2 {
|
||||
size_buf[3] = 0;
|
||||
pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ICCP)) {
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
this->setIccProfile(std::move(payload));
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF)) {
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
|
||||
byte size_buff2[2];
|
||||
// 4 meaningful bytes + 2 padding bytes
|
||||
@ -715,7 +707,7 @@ namespace Exiv2 {
|
||||
exifData_.clear();
|
||||
}
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) {
|
||||
readOrThrow(*io_, payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
io_->readOrThrow(payload.data(), payload.size(), Exiv2::kerCorruptedMetadata);
|
||||
xmpPacket_.assign(payload.c_str(), payload.size());
|
||||
if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
@ -758,9 +750,9 @@ namespace Exiv2 {
|
||||
byte webp[len];
|
||||
byte data[len];
|
||||
byte riff[len];
|
||||
readOrThrow(iIo, riff, len, Exiv2::kerCorruptedMetadata);
|
||||
readOrThrow(iIo, data, len, Exiv2::kerCorruptedMetadata);
|
||||
readOrThrow(iIo, webp, len, Exiv2::kerCorruptedMetadata);
|
||||
iIo.readOrThrow(riff, len, Exiv2::kerCorruptedMetadata);
|
||||
iIo.readOrThrow(data, len, Exiv2::kerCorruptedMetadata);
|
||||
iIo.readOrThrow(webp, len, Exiv2::kerCorruptedMetadata);
|
||||
bool matched_riff = (memcmp(riff, RiffImageId, len) == 0);
|
||||
bool matched_webp = (memcmp(webp, WebPImageId, len) == 0);
|
||||
iIo.seek(-12, BasicIo::cur);
|
||||
|
||||
BIN
test/data/exiv2-issue1941-1.exv
Normal file
BIN
test/data/exiv2-issue1941-1.exv
Normal file
Binary file not shown.
@ -971,9 +971,9 @@ File 4/16: 20040329_224245.jpg
|
||||
20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a
|
||||
20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired
|
||||
20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0
|
||||
20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0)
|
||||
20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0)
|
||||
20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0)
|
||||
20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a
|
||||
20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a
|
||||
20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a
|
||||
20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None
|
||||
20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off
|
||||
20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off
|
||||
@ -2612,9 +2612,9 @@ Compare image data and extracted data ------------------------------------
|
||||
< 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired
|
||||
< 20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off
|
||||
@ -4175,9 +4175,9 @@ Compare image data and extracted data ------------------------------------
|
||||
> 20040329_224245.exv Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired
|
||||
> 20040329_224245.exv Exif.NikonFl1.0x0009 Byte 2 0 0
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGNDistance Byte 1 None
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off
|
||||
@ -5976,9 +5976,9 @@ Compare original and inserted image data ---------------------------------
|
||||
< 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired
|
||||
< 20040329_224245.jpg Exif.NikonFl1.0x0009 Byte 2 0 0
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 (0)
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashFocalLength Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGNDistance Byte 1 None
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off
|
||||
< 20040329_224245.jpg Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off
|
||||
@ -7539,9 +7539,9 @@ Compare original and inserted image data ---------------------------------
|
||||
> 20040329_224245.exv Exif.NikonFl1.ExternalFlashFirmware Short 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.ExternalFlashFlags Byte 1 Fired
|
||||
> 20040329_224245.exv Exif.NikonFl1.0x0009 Byte 2 0 0
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 (0)
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashFocalLength Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashRate Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.RepeatingFlashCount Byte 1 n/a
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGNDistance Byte 1 None
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGroupAControlMode Byte 1 Off
|
||||
> 20040329_224245.exv Exif.NikonFl1.FlashGroupBControlMode Byte 1 Off
|
||||
|
||||
BIN
test/data/pr_1994_poc1.jpg
Normal file
BIN
test/data/pr_1994_poc1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
test/data/pr_1994_poc2.jpg
Normal file
BIN
test/data/pr_1994_poc2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
58
tests/bugfixes/github/test_issue_1941.py
Normal file
58
tests/bugfixes/github/test_issue_1941.py
Normal file
@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import system_tests
|
||||
from system_tests import CaseMeta, CopyTmpFiles, path
|
||||
|
||||
class TestNikonFl7GroupWithFlash(metaclass=CaseMeta):
|
||||
|
||||
url = "https://github.com/Exiv2/exiv2/issues/1941"
|
||||
|
||||
filename = system_tests.path("$data_path/exiv2-issue1941-1.exv")
|
||||
commands = ["""$exiv2 --grep NikonFl7 $filename"""]
|
||||
|
||||
stderr = [""]
|
||||
retval = [0]
|
||||
|
||||
stdout = ["""Exif.NikonFl7.Version Undefined 4 1.08
|
||||
Exif.NikonFl7.FlashSource Byte 1 External
|
||||
Exif.NikonFl7.ExternalFlashFirmware Short 1 5.01 (SB-900)
|
||||
Exif.NikonFl7.ExternalFlashData1 Byte 1 No external flash zoom override, external flash attached
|
||||
Exif.NikonFl7.ExternalFlashData2 Byte 1 n/a
|
||||
Exif.NikonFl7.FlashCompensation SByte 1 0
|
||||
Exif.NikonFl7.FlashFocalLength Byte 1 n/a
|
||||
Exif.NikonFl7.RepeatingFlashRate Byte 1 n/a
|
||||
Exif.NikonFl7.RepeatingFlashCount Byte 1 n/a
|
||||
Exif.NikonFl7.FlashGNDistance Byte 1 None
|
||||
Exif.NikonFl7.FlashGroupAControlData Byte 1 Manual
|
||||
Exif.NikonFl7.FlashGroupBCControlData Byte 1 Off, Off
|
||||
Exif.NikonFl7.FlashGroupAData Byte 1 4%
|
||||
Exif.NikonFl7.FlashGroupBData Byte 1 0
|
||||
Exif.NikonFl7.FlashGroupCData Byte 1 0
|
||||
"""]
|
||||
|
||||
class TestNikonFl7GroupWithoutFlash(metaclass=CaseMeta):
|
||||
|
||||
url = "https://github.com/Exiv2/exiv2/issues/1941"
|
||||
|
||||
filename = system_tests.path("$data_path/exiv2-bug1014_2.exv")
|
||||
commands = ["""$exiv2 --grep NikonFl7 $filename"""]
|
||||
|
||||
stderr = [""]
|
||||
retval = [0]
|
||||
|
||||
stdout = ["""Exif.NikonFl7.Version Undefined 4 1.07
|
||||
Exif.NikonFl7.FlashSource Byte 1 None
|
||||
Exif.NikonFl7.ExternalFlashFirmware Short 1 n/a
|
||||
Exif.NikonFl7.ExternalFlashData1 Byte 1 No external flash zoom override, external flash not attached
|
||||
Exif.NikonFl7.ExternalFlashData2 Byte 1 n/a
|
||||
Exif.NikonFl7.FlashCompensation SByte 1 0
|
||||
Exif.NikonFl7.FlashFocalLength Byte 1 n/a
|
||||
Exif.NikonFl7.RepeatingFlashRate Byte 1 n/a
|
||||
Exif.NikonFl7.RepeatingFlashCount Byte 1 n/a
|
||||
Exif.NikonFl7.FlashGNDistance Byte 1 None
|
||||
Exif.NikonFl7.FlashGroupAControlData Byte 1 Off
|
||||
Exif.NikonFl7.FlashGroupBCControlData Byte 1 Off, Off
|
||||
Exif.NikonFl7.FlashGroupAData Byte 1 0
|
||||
Exif.NikonFl7.FlashGroupBData Byte 1 0
|
||||
Exif.NikonFl7.FlashGroupCData Byte 1 0
|
||||
"""]
|
||||
38
tests/bugfixes/github/test_pr_1994.py
Normal file
38
tests/bugfixes/github/test_pr_1994.py
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import system_tests
|
||||
from system_tests import CaseMeta, path
|
||||
|
||||
class TestAddModelsForNikonFl3(metaclass=CaseMeta):
|
||||
"""
|
||||
Enables NikonFl3 group to be used by more camera models
|
||||
"""
|
||||
|
||||
filename1 = path("$data_path/pr_1994_poc1.jpg")
|
||||
filename2 = path("$data_path/pr_1994_poc2.jpg")
|
||||
commands = ["$exiv2 --grep NikonFl3 $filename1",
|
||||
"$exiv2 --grep NikonFl3 $filename2"
|
||||
]
|
||||
stdout = ["""Exif.NikonFl3.Version Undefined 4 1.04
|
||||
Exif.NikonFl3.FlashSource Byte 1 None
|
||||
Exif.NikonFl3.ExternalFlashFirmware Short 1 n/a
|
||||
Exif.NikonFl3.ExternalFlashFlags Byte 1 Fired
|
||||
Exif.NikonFl3.FlashFocalLength Byte 1 n/a
|
||||
Exif.NikonFl3.RepeatingFlashRate Byte 1 n/a
|
||||
Exif.NikonFl3.RepeatingFlashCount Byte 1 n/a
|
||||
Exif.NikonFl3.FlashGNDistance Byte 1 None
|
||||
Exif.NikonFl3.FlashColorFilter Byte 1 None
|
||||
""",
|
||||
"""Exif.NikonFl3.Version Undefined 4 1.05
|
||||
Exif.NikonFl3.FlashSource Byte 1 None
|
||||
Exif.NikonFl3.ExternalFlashFirmware Short 1 n/a
|
||||
Exif.NikonFl3.ExternalFlashFlags Byte 1 Fired
|
||||
Exif.NikonFl3.FlashFocalLength Byte 1 n/a
|
||||
Exif.NikonFl3.RepeatingFlashRate Byte 1 n/a
|
||||
Exif.NikonFl3.RepeatingFlashCount Byte 1 n/a
|
||||
Exif.NikonFl3.FlashGNDistance Byte 1 None
|
||||
Exif.NikonFl3.FlashColorFilter Byte 1 None
|
||||
"""]
|
||||
stderr = [""]*2
|
||||
retval = [0]*2
|
||||
|
||||
Loading…
Reference in New Issue
Block a user