diff --git a/MMVII/include/MMVII_ExifData.h b/MMVII/include/MMVII_ExifData.h index 6f3685987..9e3b585bf 100644 --- a/MMVII/include/MMVII_ExifData.h +++ b/MMVII/include/MMVII_ExifData.h @@ -9,14 +9,12 @@ namespace MMVII { -// FIXME CM: interface that with cDataFileIm2D (cache lazy read ?) - class cExifData { public: cExifData() {} - void reset(); + void reset(); // Reset all tags to nullopt - std::optional mExifVersion; +// Main Tags std::optional mPixelXDimension; std::optional mPixelYDimension; @@ -25,13 +23,16 @@ class cExifData { std::optional mFNumber; std::optional mExposureTime_s; - std::optional mOrientation; std::optional mMake; std::optional mModel; std::optional mLensMake; std::optional mLensModel; +// Other Tags + std::optional mExifVersion; + std::optional mOrientation; + std::optional mXResolution; std::optional mYResolution; std::optional mResolutionUnit; @@ -51,21 +52,33 @@ class cExifData { std::optional mGPSLatitude_deg; std::optional mGPSTimeStamp; std::optional mGPSDateStamp; - std::optional mGPSTimeUTC_s; + std::optional mGPSTimeUTC_s; // Unix UTC time from GPS receiver std::optional mGPSTimeUTC_ns; std::optional mDateTimeNumber_s; // Not Unix Epoch, but related to. Can be used to sort images. std::optional mDateTimeDigitizedNumber_s; std::optional mDateTimeOriginalNumber_s; +// Fill this structure from file aName (SVP: true: return false on error, false: halt program with error message) bool FromFile(const std::string &aName, bool SVP=true); +// Fill only main tags bool FromFileMainOnly(const std::string &aName, bool SVP=true); - static std::vector StringListFromFile(const std::string &aName, bool SVP=true); +/* +* static methods +*/ + +// Fill argument anExif static bool FromFile(const std::string &aName, cExifData &anExif, bool SVP=true); +// Return a struct static cExifData CreateFromFile(const std::string &aName, bool SVP=true); + +// Idem for main tags only static bool FromFileMainOnly(const std::string &aName, cExifData &anExif, bool SVP=true); static cExifData CreateFromFileMainOnly(const std::string &aName, bool SVP=true); + +// Return a list of ALL exif tags found from file + static std::vector StringListFromFile(const std::string &aName, bool SVP=true); }; diff --git a/MMVII/include/MMVII_Image2D.h b/MMVII/include/MMVII_Image2D.h index 48867f60f..c9a753913 100755 --- a/MMVII/include/MMVII_Image2D.h +++ b/MMVII/include/MMVII_Image2D.h @@ -1,6 +1,7 @@ #ifndef _MMVII_Images2D_H_ #define _MMVII_Images2D_H_ +#include "MMVII_ExifData.h" #include "MMVII_Images.h" namespace MMVII @@ -43,8 +44,11 @@ class cDataFileIm2D : public cRect2 const int & NbChannel () const ; ///< std accessor const eTyNums & Type () const ; ///< std accessor const std::string & Name() const; ///< std accessor - bool IsEmpty() const; - void AssertNotEmpty() const; + bool IsEmpty() const; + void AssertNotEmpty() const; + const cExifData& ExifDataAll(bool SVP=true) const; + const cExifData& ExifDataMain(bool SVP=true) const; + std::vector ExifStrings(bool SVP=true) const; /// Create a descriptor on existing file static cDataFileIm2D Create(const std::string & aName,eForceGray); @@ -67,13 +71,14 @@ class cDataFileIm2D : public cRect2 virtual ~cDataFileIm2D(); - static bool IsPostFixNameImage(const std::string & aPost); - static bool IsNameWith_PostFixImage(const std::string & aPost); + static bool IsPostFixNameImage(const std::string & aPost); + static bool IsNameWith_PostFixImage(const std::string & aPost); eForceGray ForceGray() const; ///< Accessor private : friend class cGdalApi; enum class eCreationState {Created, AtFirstWrite, CreatedNoUpdate}; + enum class eExifState {NotRead, MainTagsRead, AllTagsRead}; cDataFileIm2D(const std::string &,eTyNums,const cPt2di & aSz,int aNbChannel, const tOptions& aOptions, eForceGray, eCreationState) ; void SetCreated() const; @@ -85,6 +90,8 @@ class cDataFileIm2D : public cRect2 int mNbChannel; ///< Number of channels eForceGray mForceGray; tOptions mCreateOptions; ///< GDAL Creations options, depend of output driver (JPEG, TIFF, ...) + mutable cExifData mExifData; + mutable eExifState mExifState; mutable eCreationState mCreationState; ///< support for creation of non updatable file image (create/write at once: .png, .jpg, ...) }; diff --git a/MMVII/src/ImagesBase/AppliExifData.cpp b/MMVII/src/ImagesBase/AppliExifData.cpp index e9eba8604..6361a2a8d 100755 --- a/MMVII/src/ImagesBase/AppliExifData.cpp +++ b/MMVII/src/ImagesBase/AppliExifData.cpp @@ -1,4 +1,5 @@ #include "MMVII_ExifData.h" +#include "MMVII_Image2D.h" #include "cMMVII_Appli.h" namespace MMVII @@ -44,25 +45,22 @@ std::ostream& operator<<(std::ostream& os, std::optional const& opt) int cAppli_ExifData::Exe() { + const auto default_precision{std::cout.precision()}; + constexpr auto max_precision{std::numeric_limits::digits10}; + for (const auto & aName : VectMainSet(0)) { - std::cout << "####### " << aName <<":" << std::endl; + auto aDataFileIm=cDataFileIm2D::Create(aName,eForceGray::No); + std::cout << "####### " << aDataFileIm.Name() <<":" << std::endl; if (mDisp == 2) { - auto anExifList = cExifData::StringListFromFile(aName); + auto anExifList = aDataFileIm.ExifStrings(); for (const auto &s : anExifList) std::cout << s << std::endl; } else { - cExifData anExif; - if (mDisp == 0) - anExif = cExifData::CreateFromFile(aName); - else - anExif = cExifData::CreateFromFileMainOnly(aName); - std::cout << std::setprecision(17); + cExifData anExif = mDisp == 0 ? aDataFileIm.ExifDataAll() : aDataFileIm.ExifDataMain(); #define DISP_EXIF(key) std::cout << #key << ": " << anExif.m##key << std::endl; - DISP_EXIF(ExifVersion); - DISP_EXIF(PixelXDimension); DISP_EXIF(PixelYDimension); @@ -75,6 +73,7 @@ int cAppli_ExifData::Exe() DISP_EXIF(Model); DISP_EXIF(LensMake); DISP_EXIF(LensModel); + if (mDisp == 0) { DISP_EXIF(XResolution); DISP_EXIF(YResolution); @@ -90,6 +89,7 @@ int cAppli_ExifData::Exe() DISP_EXIF(DateTimeDigitized); DISP_EXIF(SubSecTimeDigitized); + std::cout << std::setprecision(max_precision); DISP_EXIF(DateTimeNumber_s); DISP_EXIF(DateTimeOriginalNumber_s); DISP_EXIF(DateTimeDigitizedNumber_s); @@ -97,6 +97,7 @@ int cAppli_ExifData::Exe() DISP_EXIF(GPSLongitude_deg); DISP_EXIF(GPSLatitude_deg); DISP_EXIF(GPSAltitude_m); + std::cout << std::setprecision(default_precision); DISP_EXIF(GPSDateStamp); DISP_EXIF(GPSTimeStamp); @@ -105,6 +106,8 @@ int cAppli_ExifData::Exe() DISP_EXIF(ExifVersion); } + std::cout << std::setprecision(default_precision); +#undef DISP_EXIF } std::cout << std::endl; } diff --git a/MMVII/src/ImagesBase/FileImages.cpp b/MMVII/src/ImagesBase/FileImages.cpp index c16ffb232..4c47106b7 100644 --- a/MMVII/src/ImagesBase/FileImages.cpp +++ b/MMVII/src/ImagesBase/FileImages.cpp @@ -88,6 +88,7 @@ cDataFileIm2D::cDataFileIm2D(const std::string & aName, eTyNums aType, const cPt mNbChannel (aNbChannel), mForceGray (isFG), mCreateOptions (aOptions), + mExifState (eExifState::NotRead), mCreationState (aCreationState) { } @@ -219,6 +220,32 @@ void cDataFileIm2D::SetCreatedNoUpdate() const mCreationState = eCreationState::CreatedNoUpdate; } +const cExifData& cDataFileIm2D::ExifDataAll(bool SVP) const +{ + if (mExifState != eExifState::AllTagsRead) + { + mExifData.FromFile(mName,SVP); + mExifState = eExifState::AllTagsRead; + + } + return mExifData; +} + +const cExifData& cDataFileIm2D::ExifDataMain(bool SVP) const +{ + if (mExifState != eExifState::MainTagsRead && mExifState != eExifState::AllTagsRead) + { + mExifData.FromFileMainOnly(mName,SVP); + mExifState = eExifState::MainTagsRead; + } + return mExifData; +} + +std::vector cDataFileIm2D::ExifStrings(bool SVP) const +{ + return cExifData::StringListFromFile(mName,SVP); +} + bool cDataFileIm2D::IsPostFixNameImage(const std::string & aPost)