Add EXIV2_ENABLE_FILESYSTEM_ACCESS option

main
Miguel Borges de Freitas 2 years ago committed by Rosen Penev
parent 9f90144e89
commit aa88bc4a43

@ -46,6 +46,7 @@ option(EXIV2_ENABLE_BMFF "Build with BMFF support" ON)
option(EXIV2_ENABLE_BROTLI "Use Brotli for JPEG XL compressed boxes (BMFF)" ON)
option(EXIV2_ENABLE_VIDEO "Build with video support" ON)
option(EXIV2_ENABLE_INIH "Use inih library" ON)
option(EXIV2_ENABLE_FILESYSTEM_ACCESS "Build with filesystem access" ON)
option(EXIV2_BUILD_SAMPLES "Build sample applications" OFF)
option(EXIV2_BUILD_EXIV2_COMMAND "Build exiv2 command-line executable" ON)
@ -100,18 +101,22 @@ include(cmake/compilerFlagsExiv2.cmake REQUIRED)
add_subdirectory(src)
if(BUILD_TESTING AND EXIV2_BUILD_UNIT_TESTS)
set(EXIV2_ENABLE_FILESYSTEM_ACCESS ON)
add_subdirectory(unitTests)
endif()
if(EXIV2_BUILD_FUZZ_TESTS)
set(EXIV2_ENABLE_FILESYSTEM_ACCESS ON)
add_subdirectory(fuzz)
endif()
if(EXIV2_BUILD_EXIV2_COMMAND)
add_subdirectory(app)
set(EXIV2_ENABLE_FILESYSTEM_ACCESS ON)
if(EXIV2_BUILD_SAMPLES)
add_subdirectory(samples)
set(EXIV2_ENABLE_FILESYSTEM_ACCESS ON)
get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS)
if(BUILD_TESTING AND Python3_Interpreter_FOUND)

@ -252,6 +252,7 @@ option( EXIV2_ENABLE_PNG "Build with png support (requires libz)"
...
option( EXIV2_ENABLE_BMFF "Build with BMFF support (brotli recommended)" ON )
option( EXIV2_ENABLE_BROTLI "Use Brotli for JPEG XL compressed boxes (BMFF)" ON )
option( EXIV2_ENABLE_FILESYSTEM_ACCESS "Build with filesystem access" ON )
577 rmills@rmillsmm:~/gnu/github/exiv2/exiv2 $
```

@ -6,6 +6,9 @@
// Define to 1 if you want to use libcurl in httpIO.
#cmakedefine EXV_USE_CURL
// Define to 1 if you want to enable filesystem access
#cmakedefine EXV_ENABLE_FILESYSTEM
// Define if you require webready support.
#cmakedefine EXV_ENABLE_WEBREADY

@ -37,7 +37,9 @@ if(BUILD_TESTING)
endif()
endif()
find_package(Filesystem COMPONENTS Experimental Final REQUIRED)
if(EXIV2_ENABLE_FILESYSTEM_ACCESS)
find_package(Filesystem COMPONENTS Experimental Final REQUIRED)
endif()
# don't use Frameworks on the Mac (#966)
if (APPLE)

@ -6,10 +6,11 @@ include(CheckCXXSymbolExists)
if (${EXIV2_ENABLE_WEBREADY})
set(EXV_USE_CURL ${EXIV2_ENABLE_CURL})
endif()
set(EXV_ENABLE_BMFF ${EXIV2_ENABLE_BMFF})
set(EXV_ENABLE_WEBREADY ${EXIV2_ENABLE_WEBREADY})
set(EXV_HAVE_LENSDATA ${EXIV2_ENABLE_LENSDATA})
set(EXV_ENABLE_INIH ${EXIV2_ENABLE_INIH})
set(EXV_ENABLE_BMFF ${EXIV2_ENABLE_BMFF})
set(EXV_ENABLE_WEBREADY ${EXIV2_ENABLE_WEBREADY})
set(EXV_HAVE_LENSDATA ${EXIV2_ENABLE_LENSDATA})
set(EXV_ENABLE_INIH ${EXIV2_ENABLE_INIH})
set(EXV_ENABLE_FILESYSTEM ${EXIV2_ENABLE_FILESYSTEM_ACCESS})
set(EXV_PACKAGE_NAME ${PROJECT_NAME})
set(EXV_PACKAGE_VERSION ${PROJECT_VERSION})

@ -69,4 +69,5 @@ OptionOutput( "Building unit tests: " EXIV2_BUILD_UNIT_TESTS AND
OptionOutput( "Building fuzz tests: " EXIV2_BUILD_FUZZ_TESTS )
OptionOutput( "Building doc: " EXIV2_BUILD_DOC )
OptionOutput( "Building with coverage flags: " BUILD_WITH_COVERAGE )
OptionOutput( "Building with filesystem access " EXIV2_ENABLE_FILESYSTEM_ACCESS )
OptionOutput( "Using ccache: " BUILD_WITH_CCACHE )

@ -276,6 +276,7 @@ class EXIV2API IoCloser {
IoCloser& operator=(const IoCloser&) = delete;
}; // class IoCloser
#ifdef EXV_ENABLE_FILESYSTEM
/*!
@brief Provides binary file IO by implementing the BasicIo
interface.
@ -479,6 +480,7 @@ class EXIV2API FileIo : public BasicIo {
std::unique_ptr<Impl> p_;
}; // class FileIo
#endif
/*!
@brief Provides binary IO on blocks of memory by implementing the BasicIo
@ -686,7 +688,7 @@ class EXIV2API XPathIo : public MemIo {
*/
void ReadDataUri(const std::string& path);
}; // class XPathIo
#else
#elif defined(EXV_ENABLE_FILESYSTEM)
class EXIV2API XPathIo : public FileIo {
public:
/*!

@ -229,6 +229,7 @@ class EXIV2API ExifThumbC {
data buffer and %DataBuf ensures that it will be deleted.
*/
[[nodiscard]] DataBuf copy() const;
#ifdef EXV_ENABLE_FILESYSTEM
/*!
@brief Write the thumbnail image to a file.
@ -240,6 +241,7 @@ class EXIV2API ExifThumbC {
@return The number of bytes written.
*/
[[nodiscard]] size_t writeFile(const std::string& path) const;
#endif
/*!
@brief Return the MIME type of the thumbnail, either \c "image/tiff"
or \c "image/jpeg".
@ -279,6 +281,7 @@ class EXIV2API ExifThumb : public ExifThumbC {
//! @name Manipulators
//@{
#ifdef EXV_ENABLE_FILESYSTEM
/*!
@brief Set the Exif thumbnail to the JPEG image \em path. Set
XResolution, YResolution and ResolutionUnit to \em xres,
@ -297,6 +300,7 @@ class EXIV2API ExifThumb : public ExifThumbC {
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit);
#endif
/*!
@brief Set the Exif thumbnail to the JPEG image pointed to by \em buf,
and size \em size. Set XResolution, YResolution and
@ -315,6 +319,7 @@ class EXIV2API ExifThumb : public ExifThumbC {
application that comes with OS X for one.) - David Harvey.
*/
void setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit);
#ifdef EXV_ENABLE_FILESYSTEM
/*!
@brief Set the Exif thumbnail to the JPEG image \em path.
@ -329,6 +334,7 @@ class EXIV2API ExifThumb : public ExifThumbC {
@note Additional existing Exif thumbnail tags are not modified.
*/
void setJpegThumbnail(const std::string& path);
#endif
/*!
@brief Set the Exif thumbnail to the JPEG image pointed to by \em buf,
and size \em size.

@ -68,6 +68,7 @@ class EXIV2API PreviewImage {
@brief Return the size of the preview image in bytes.
*/
[[nodiscard]] uint32_t size() const;
#ifdef EXV_ENABLE_FILESYSTEM
/*!
@brief Write the thumbnail image to a file.
@ -79,6 +80,7 @@ class EXIV2API PreviewImage {
@return The number of bytes written.
*/
[[nodiscard]] size_t writeFile(const std::string& path) const;
#endif
/*!
@brief Return the MIME type of the preview image, usually either
\c "image/tiff" or \c "image/jpeg".

@ -121,6 +121,7 @@ cdata.set('EXV_HAVE_LIBZ', zlib_dep.found())
cdata.set('EXV_ENABLE_WEBREADY', get_option('webready'))
cdata.set('EXV_USE_CURL', curl_dep.found())
cdata.set('EXV_ENABLE_NLS', intl_dep.found())
cdata.set('EXV_ENABLE_FILESYSTEM', true)
cfile = configure_file(
input: 'cmake/config.h.cmake',

@ -35,6 +35,7 @@
#include <curl/curl.h>
#endif
#ifdef EXV_ENABLE_FILESYSTEM
#ifdef _WIN32
#include <io.h>
#include <windows.h>
@ -47,19 +48,7 @@ namespace fs = std::filesystem;
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
// *****************************************************************************
// class member definitions
namespace {
/// @brief replace each substring of the subject that matches the given search string with the given replacement.
void ReplaceStringInPlace(std::string& subject, std::string_view search, std::string_view replace) {
auto pos = subject.find(search);
while (pos != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += subject.find(search, pos + replace.length());
}
}
} // namespace
#endif
namespace Exiv2 {
void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) {
@ -73,6 +62,7 @@ void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) {
Internal::enforce(r == 0, err);
}
#ifdef EXV_ENABLE_FILESYSTEM
//! Internal Pimpl structure of class FileIo.
class FileIo::Impl {
public:
@ -550,6 +540,7 @@ const std::string& FileIo::path() const noexcept {
void FileIo::populateFakeData() {
}
#endif
//! Internal Pimpl structure of class MemIo.
class MemIo::Impl final {
@ -898,7 +889,7 @@ void XPathIo::ReadDataUri(const std::string& path) {
delete[] decodeData;
}
#else
#elif defined(EXV_ENABLE_FILESYSTEM)
XPathIo::XPathIo(const std::string& orgPath) : FileIo(XPathIo::writeDataToFile(orgPath)), tempFilePath_(path()) {
}
@ -913,6 +904,16 @@ void XPathIo::transfer(BasicIo& src) {
if (isTemp_) {
// replace temp path to gent path.
auto currentPath = path();
// replace each substring of the subject that matches the given search string with the given replacement.
auto ReplaceStringInPlace = [](std::string& subject, std::string_view search, std::string_view replace) {
auto pos = subject.find(search);
while (pos != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += subject.find(search, pos + replace.length());
}
};
ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT);
setPath(currentPath);
@ -1707,7 +1708,7 @@ CurlIo::CurlIo(const std::string& url, size_t blockSize) {
// *************************************************************************
// free functions
#ifdef EXV_ENABLE_FILESYSTEM
DataBuf readFile(const std::string& path) {
FileIo file(path);
if (file.open("rb") != 0) {
@ -1727,6 +1728,7 @@ size_t writeFile(const DataBuf& buf, const std::string& path) {
}
return file.write(buf.c_data(), buf.size());
}
#endif
#ifdef EXV_USE_CURL
size_t curlWriter(char* data, size_t size, size_t nmemb, std::string* writerData) {

@ -375,6 +375,7 @@ DataBuf ExifThumbC::copy() const {
return thumbnail->copy(exifData_);
}
#ifdef EXV_ENABLE_FILESYSTEM
size_t ExifThumbC::writeFile(const std::string& path) const {
auto thumbnail = Thumbnail::create(exifData_);
if (!thumbnail)
@ -387,6 +388,7 @@ size_t ExifThumbC::writeFile(const std::string& path) const {
return Exiv2::writeFile(buf, name);
}
#endif
const char* ExifThumbC::mimeType() const {
auto thumbnail = Thumbnail::create(exifData_);
@ -405,10 +407,12 @@ const char* ExifThumbC::extension() const {
ExifThumb::ExifThumb(ExifData& exifData) : ExifThumbC(exifData), exifData_(exifData) {
}
#ifdef EXV_ENABLE_FILESYSTEM
void ExifThumb::setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit) {
DataBuf thumb = readFile(path); // may throw
setJpegThumbnail(thumb.c_data(), thumb.size(), xres, yres, unit);
}
#endif
void ExifThumb::setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit) {
setJpegThumbnail(buf, size);
@ -417,10 +421,12 @@ void ExifThumb::setJpegThumbnail(const byte* buf, size_t size, URational xres, U
exifData_["Exif.Thumbnail.ResolutionUnit"] = unit;
}
#ifdef EXV_ENABLE_FILESYSTEM
void ExifThumb::setJpegThumbnail(const std::string& path) {
DataBuf thumb = readFile(path); // may throw
setJpegThumbnail(thumb.c_data(), thumb.size());
}
#endif
void ExifThumb::setJpegThumbnail(const byte* buf, size_t size) {
exifData_["Exif.Thumbnail.Compression"] = static_cast<uint16_t>(6);

@ -15,6 +15,7 @@
#include <sstream>
#include <stdexcept>
#ifdef EXV_ENABLE_FILESYSTEM
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
@ -22,6 +23,7 @@ namespace fs = std::filesystem;
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
#endif
#if defined(_WIN32)
// clang-format off
@ -231,7 +233,11 @@ bool fileExists(const std::string& path) {
if (fileProtocol(path) != pFile) {
return true;
}
#ifdef EXV_ENABLE_FILESYSTEM
return fs::exists(path);
#else
return false;
#endif
}
std::string strError() {
@ -341,6 +347,7 @@ Uri Uri::Parse(const std::string& uri) {
}
std::string getProcessPath() {
#ifdef EXV_ENABLE_FILESYSTEM
#if defined(__FreeBSD__)
std::string ret("unknown");
unsigned int n;
@ -382,5 +389,8 @@ std::string getProcessPath() {
return "unknown";
}
#endif
#else
return "unknown";
#endif
}
} // namespace Exiv2

@ -120,11 +120,13 @@ constexpr Registry registry[] = {
#endif // EXV_ENABLE_BMFF
};
#ifdef EXV_ENABLE_FILESYSTEM
std::string pathOfFileUrl(const std::string& url) {
std::string path = url.substr(7);
size_t found = path.find('/');
return (found == std::string::npos) ? path : path.substr(found);
}
#endif
} // namespace
@ -782,9 +784,13 @@ bool ImageFactory::checkType(ImageType type, BasicIo& io, bool advance) {
return false;
}
ImageType ImageFactory::getType(const std::string& path) {
ImageType ImageFactory::getType([[maybe_unused]] const std::string& path) {
#ifdef EXV_ENABLE_FILESYSTEM
FileIo fileIo(path);
return getType(fileIo);
#else
return ImageType::none;
#endif
}
ImageType ImageFactory::getType(const byte* data, size_t size) {
@ -817,12 +823,16 @@ BasicIo::UniquePtr ImageFactory::createIo(const std::string& path, [[maybe_unuse
if (fProt == pHttp)
return std::make_unique<HttpIo>(path); // may throw
#endif
#ifdef EXV_ENABLE_FILESYSTEM
if (fProt == pFileUri)
return std::make_unique<FileIo>(pathOfFileUrl(path));
if (fProt == pStdin || fProt == pDataUri)
return std::make_unique<XPathIo>(path); // may throw
return std::make_unique<FileIo>(path);
#else
return nullptr;
#endif
} // ImageFactory::createIo
Image::UniquePtr ImageFactory::open(const std::string& path, bool useCurl) {
@ -851,6 +861,7 @@ Image::UniquePtr ImageFactory::open(BasicIo::UniquePtr io) {
return nullptr;
}
#ifdef EXV_ENABLE_FILESYSTEM
Image::UniquePtr ImageFactory::create(ImageType type, const std::string& path) {
auto fileIo = std::make_unique<FileIo>(path);
// Create or overwrite the file, then close it
@ -865,6 +876,7 @@ Image::UniquePtr ImageFactory::create(ImageType type, const std::string& path) {
throw Error(ErrorCode::kerUnsupportedImageType, static_cast<int>(type));
return image;
}
#endif
Image::UniquePtr ImageFactory::create(ImageType type) {
auto image = create(type, std::make_unique<MemIo>());

@ -18,6 +18,7 @@
#include <array>
#include <iostream>
#ifdef EXV_ENABLE_FILESYSTEM
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
@ -25,6 +26,7 @@ namespace fs = std::filesystem;
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
#endif
#if !defined(_WIN32)
#include <pwd.h>
@ -59,6 +61,7 @@ namespace Exiv2::Internal {
// If not found in cwd, we return the default path
// which is the user profile path on win and the home dir on linux
std::string getExiv2ConfigPath() {
#ifdef EXV_ENABLE_FILESYSTEM
#ifdef _WIN32
std::string inifile("exiv2.ini");
#else
@ -81,13 +84,16 @@ std::string getExiv2ConfigPath() {
currentPath = std::string(pw ? pw->pw_dir : "");
#endif
return (currentPath / inifile).string();
#else
return "";
#endif
}
std::string readExiv2Config([[maybe_unused]] const std::string& section, [[maybe_unused]] const std::string& value,
const std::string& def) {
std::string result = def;
#ifdef EXV_ENABLE_INIH
#if defined(EXV_ENABLE_INIH) && defined(EXV_ENABLE_FILESYSTEM)
INIReader reader(Exiv2::Internal::getExiv2ConfigPath());
if (reader.ParseError() == 0) {
result = reader.Get(section, value, def);

@ -967,12 +967,14 @@ PreviewImage& PreviewImage::operator=(const PreviewImage& rhs) {
return *this;
}
#ifdef EXV_ENABLE_FILESYSTEM
size_t PreviewImage::writeFile(const std::string& path) const {
std::string name = path + extension();
// Todo: Creating a DataBuf here unnecessarily copies the memory
DataBuf buf(pData(), size());
return Exiv2::writeFile(buf, name);
}
#endif
DataBuf PreviewImage::copy() const {
return {pData(), size()};

@ -1099,7 +1099,7 @@ size_t TiffBinaryArray::doWrite(IoWrapper& ioWrapper, ByteOrder byteOrder, size_
}
DataBuf buf = cryptFct(tag(), mio.mmap(), mio.size(), pRoot_);
if (!buf.empty()) {
mio.seek(0, Exiv2::FileIo::beg);
mio.seek(0, Exiv2::BasicIo::beg);
mio.write(buf.c_data(), buf.size());
}
}

Loading…
Cancel
Save