Skip to content

Commit

Permalink
wip: add support for relative path names
Browse files Browse the repository at this point in the history
This uses a C++-17 library feature for filesystem, which is pretty widely supported
but still an additional requirement
  • Loading branch information
bradh committed Feb 14, 2024
1 parent 5cbc793 commit 72c2bb2
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 12 deletions.
2 changes: 2 additions & 0 deletions libheif/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ target_compile_definitions(heif
LIBHEIF_EXPORTS
HAVE_VISIBILITY)

target_compile_features(heif PRIVATE cxx_std_17)

if (PLUGIN_LOADING_SUPPORTED_AND_ENABLED)
target_compile_definitions(heif PRIVATE ENABLE_PLUGIN_LOADING=1)
target_link_libraries(heif PRIVATE ${CMAKE_DL_LIBS})
Expand Down
14 changes: 8 additions & 6 deletions libheif/box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,7 @@ Error Box_iloc::read_data(const Item& item,
const std::shared_ptr<StreamReader>& istr,
const std::shared_ptr<Box_idat>& idat,
const std::shared_ptr<Box_dinf>& dinf,
const std::filesystem::path base_path,
std::vector<uint8_t>* dest) const
{
// TODO: this function should always append the data to the output vector as this is used when
Expand Down Expand Up @@ -1313,11 +1314,12 @@ Error Box_iloc::read_data(const Item& item,
(void) success;
} else {
std::string location = urlBox->get_location();
#if defined(__MINGW32__) || defined(__MINGW64__) || defined(_MSC_VER)
auto input_stream_istr = std::unique_ptr<std::istream>(new std::ifstream(convert_utf8_path_to_utf16(location).c_str(), std::ios_base::binary));
#else
auto datafile_istr = std::unique_ptr<std::istream>(new std::ifstream(location.c_str(), std::ios_base::binary));
#endif
// TODO: handle case where its really a URL
std::filesystem::path locationPath(location);
if (locationPath.is_relative()) {
locationPath = base_path / locationPath;
}
auto datafile_istr = std::unique_ptr<std::istream>(new std::ifstream(locationPath, std::ios_base::binary));
if (!datafile_istr->good()) {
std::stringstream sstr;
sstr << "Error opening file: " << location << ", " << strerror(errno) << " (" << errno << ")\n";
Expand All @@ -1331,7 +1333,7 @@ Error Box_iloc::read_data(const Item& item,
}
} else {
std::stringstream sstr;
sstr << "Item construction method 2 with data reference type " << dataentry->get_type_string() << "is not implemented";
sstr << "Item construction method 2 with data reference type " << dataentry->get_type_string() << " is not implemented";
return Error(heif_error_Unsupported_feature,
heif_suberror_Unsupported_item_construction_method,
sstr.str());
Expand Down
2 changes: 2 additions & 0 deletions libheif/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <istream>
#include <bitset>
#include <utility>
#include <filesystem>

#include "error.h"
#include "heif.h"
Expand Down Expand Up @@ -392,6 +393,7 @@ class Box_iloc : public FullBox
const std::shared_ptr<StreamReader>& istr,
const std::shared_ptr<class Box_idat>&,
const std::shared_ptr<class Box_dinf>&,
const std::filesystem::path base_path,
std::vector<uint8_t>* dest) const;

void set_min_version(uint8_t min_version) { m_user_defined_min_version = min_version; }
Expand Down
18 changes: 12 additions & 6 deletions libheif/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "libheif/vvc.h"

#include <cstdint>
#include <filesystem>
#include <fstream>
#include <limits>
#include <sstream>
Expand Down Expand Up @@ -83,7 +84,12 @@ Error HeifFile::read_from_file(const char* input_filename)
sstr << "Error opening file: " << strerror(errno) << " (" << errno << ")\n";
return Error(heif_error_Input_does_not_exist, heif_suberror_Unspecified, sstr.str());
}

std::filesystem::path input_path(input_filename);
if (input_path.has_parent_path()) {
m_base_path = input_path.parent_path();
} else {
m_base_path.clear();
}
auto input_stream = std::make_shared<StreamReader_istream>(std::move(input_stream_istr));
return read(input_stream);
}
Expand Down Expand Up @@ -776,7 +782,7 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
heif_suberror_No_item_data);
}

error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, data);
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, m_base_path, data);
}
else if (item_type == "av01") {
// --- --- --- AV1
Expand Down Expand Up @@ -812,7 +818,7 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
heif_suberror_No_item_data);
}

error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, data);
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, m_base_path, data);
}
else if (item_type == "jpeg" ||
(item_type == "mime" && get_content_type(ID) == "image/jpeg")) {
Expand All @@ -838,7 +844,7 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
}
}

error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, data);
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, m_base_path, data);
}
else if (item_type == "j2k1") {
std::vector<std::shared_ptr<Box>> properties;
Expand Down Expand Up @@ -872,7 +878,7 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
// heif_suberror_No_item_data);
// }

error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, data);
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, m_base_path, data);
}
else if (true || // fallback case for all kinds of generic metadata (e.g. 'iptc')
item_type == "grid" ||
Expand All @@ -898,7 +904,7 @@ Error HeifFile::get_compressed_image_data(heif_item_id ID, std::vector<uint8_t>*
}

if (read_uncompressed) {
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, data);
error = m_iloc_box->read_data(*item, m_input_stream, m_idat_box, m_dinf_box, m_base_path, data);
}
}

Expand Down
2 changes: 2 additions & 0 deletions libheif/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "hevc.h"
#include "nclx.h"

#include <filesystem>
#include <map>
#include <memory>
#include <string>
Expand Down Expand Up @@ -206,6 +207,7 @@ class HeifFile
#endif

std::shared_ptr<StreamReader> m_input_stream;
std::filesystem::path m_base_path;

std::vector<std::shared_ptr<Box> > m_top_level_boxes;

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ configure_file(test-config.cc.in ${CMAKE_BINARY_DIR}/generated/test-config.cc)
macro(add_libheif_test TEST_FILE)
set(TEST_NAME ${TEST_FILE})
add_executable(${TEST_NAME} main.cc catch.hpp ${CMAKE_BINARY_DIR}/generated/test-config.cc test_utils.cc ${TEST_FILE}.cc)
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
target_link_libraries(${TEST_NAME} PRIVATE heif)
add_test(NAME ${TEST_NAME} COMMAND ./${TEST_NAME})
endmacro()
Expand Down

0 comments on commit 72c2bb2

Please sign in to comment.