Merge branch 'main' into fix_exiv2_-pR

This commit is contained in:
Kevin Backhouse 2021-11-24 12:58:53 +00:00 committed by GitHub
commit 6758e7288d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 578 additions and 127 deletions

View File

@ -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')

View File

@ -76,6 +76,7 @@ TABLES = Exif \
NikonFl1 \
NikonFl2 \
NikonFl3 \
NikonFl7 \
NikonSiD80 \
NikonSiD40 \
NikonSiD300a \

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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() )

View File

@ -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);
}

View File

@ -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*/)

View File

@ -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;

View File

@ -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

View File

@ -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 },

View File

@ -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>
/*!

View File

@ -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 },

View File

@ -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);

Binary file not shown.

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
test/data/pr_1994_poc2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View 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
"""]

View 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