diff --git a/avdict/CMakeLists.txt b/avdict/CMakeLists.txt index f409c13..84842b0 100644 --- a/avdict/CMakeLists.txt +++ b/avdict/CMakeLists.txt @@ -13,6 +13,7 @@ include(GetLinkLibraries) find_package(AVUTIL REQUIRED) add_library(avdict STATIC avdict.h src/avdict.c) +include_directories("${AVUTIL_INCLUDE_DIRS}") target_link_libraries(avdict AVUTIL::AVUTIL) target_compile_definitions(avdict PRIVATE -DBUILD_AVDICT) diff --git a/build.rs b/build.rs index 176ca9d..f49541f 100644 --- a/build.rs +++ b/build.rs @@ -136,6 +136,7 @@ fn main() { // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .no_copy("ExifDataRef") // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. diff --git a/exif/exif.h b/exif/exif.h index e4614a6..cbbe478 100644 --- a/exif/exif.h +++ b/exif/exif.h @@ -15,6 +15,8 @@ typedef struct ExifValue ExifValue; typedef struct ExifData ExifData; ///
typedef struct ExifDatum ExifDatum; +/// +typedef struct ExifDataRef ExifDataRef; #if defined _WIN32 && defined WIN32_DLL #if BUILD_DLL #define EXIF_API __declspec(dllexport) @@ -26,6 +28,7 @@ typedef struct ExifDatum ExifDatum; #endif EXIF_API ExifImage* create_exif_image(const char* path); +EXIF_API const ExifDataRef* exif_image_get_exif_data(ExifImage* image); EXIF_API int exif_image_set_exif_data(ExifImage* image, ExifData* data); EXIF_API int exif_image_write_metadata(ExifImage* image); EXIF_API void free_exif_image(ExifImage* img); @@ -54,8 +57,10 @@ EXIF_API int64_t exif_value_to_int64(ExifValue* value, long i); EXIF_API ExifData* exif_data_new(); EXIF_API int exif_data_add(ExifData* d, ExifKey* key, ExifValue* value); EXIF_API int exif_data_clear(ExifData* d); -EXIF_API int exif_data_is_empty(ExifData* d); -EXIF_API long exif_data_get_count(ExifData* d); +EXIF_API const ExifDataRef* exif_data_get_ref(ExifData* d); +EXIF_API ExifData* exif_data_ref_clone(ExifDataRef* d); +EXIF_API int exif_data_ref_is_empty(ExifDataRef* d); +EXIF_API long exif_data_ref_get_count(ExifDataRef* d); EXIF_API void exif_free_value(ExifValue* value); EXIF_API void exif_free_data(ExifData* d); EXIF_API void exif_free_datum(ExifDatum* d); diff --git a/exif/src/exif.cpp b/exif/src/exif.cpp index d7338a8..707917c 100644 --- a/exif/src/exif.cpp +++ b/exif/src/exif.cpp @@ -24,6 +24,12 @@ end: return nullptr; } +const ExifDataRef* exif_image_get_exif_data(ExifImage* image) { + if (!image || !image->image) return nullptr; + image->exif_data_ref.data = &image->image->exifData(); + return &image->exif_data_ref; +} + int exif_image_set_exif_data(ExifImage* image, ExifData* data) { if (!image || !data) return 1; image->image->setExifData(data->data); @@ -230,14 +236,36 @@ int exif_data_clear(ExifData* d) { return 1; } -int exif_data_is_empty(ExifData* d) { - if (!d) return -1; - return d->data.empty() ? 1 : 0; +const ExifDataRef* exif_data_get_ref(ExifData* d) { + if (!d) return nullptr; + d->ref.data = &d->data; + return &d->ref; } -long exif_data_get_count(ExifData* d) { - if (!d) return -1; - return d->data.count(); +ExifData* exif_data_ref_clone(ExifDataRef* d) { + if (!d || !d->data) return nullptr; + auto n = new ExifData; + if (!n) return nullptr; + try { + for (auto i = d->data->begin(); i != d->data->end(); ++i) { + n->data.add(*i); + } + } catch (std::exception& e) { + printf("%s\n", e.what()); + delete n; + return nullptr; + } + return n; +} + +int exif_data_ref_is_empty(ExifDataRef* d) { + if (!d || !d->data) return -1; + return d->data->empty() ? 1 : 0; +} + +long exif_data_ref_get_count(ExifDataRef* d) { + if (!d || !d->data) return -1; + return d->data->count(); } void exif_free_value(ExifValue* value) { diff --git a/exif/src/exif_priv.h b/exif/src/exif_priv.h index 296684e..67789e9 100644 --- a/exif/src/exif_priv.h +++ b/exif/src/exif_priv.h @@ -1,8 +1,12 @@ #ifndef _EXIF_EXIF_PRIV_H #define _EXIF_EXIF_PRIV_H #include "exiv2/exiv2.hpp" +typedef struct ExifDataRef { + const Exiv2::ExifData* data = nullptr; +} ExifDataRef; typedef struct ExifImage { Exiv2::Image::UniquePtr image; + ExifDataRef exif_data_ref; } ExifImage; typedef struct ExifKey { Exiv2::ExifKey* key = nullptr; @@ -12,6 +16,7 @@ typedef struct ExifValue { } ExifValue; typedef struct ExifData { Exiv2::ExifData data; + ExifDataRef ref; } ExifData; typedef struct ExifDatum { Exiv2::Exifdatum* data; diff --git a/src/exif.rs b/src/exif.rs index 8fc9362..c20cc65 100644 --- a/src/exif.rs +++ b/src/exif.rs @@ -1,7 +1,12 @@ use crate::_exif; +use crate::_exif::ExifDataRef; +use crate::ext::rawhandle::FromRawHandle; use crate::ext::rawhandle::ToRawHandle; use c_fixed_string::CFixedStr; use int_enum::IntEnum; +use std::borrow::Borrow; +use std::borrow::ToOwned; +use std::clone::Clone; use std::convert::TryFrom; use std::ffi::CStr; use std::ffi::CString; @@ -10,6 +15,7 @@ use std::ffi::OsStr; use std::fs::copy; #[cfg(test)] use std::fs::create_dir; +use std::ops::Deref; use std::ops::Drop; use std::os::raw::c_long; use std::path::Path; @@ -500,6 +506,10 @@ impl ExifData { Ok(Self { data: d }) } + pub unsafe fn from_raw_pointer(data: *mut _exif::ExifData) -> Self { + Self { data } + } + /// Add a data from the supplied key and value pair. /// No duplicate checks are performed, i.e., it is possible to add multiple metadata with the same key. pub fn add(&mut self, key: &ExifKey, value: &ExifValue) -> Result<(), ()> { @@ -529,32 +539,18 @@ impl ExifData { Ok(()) } } +} - /// Get the number of metadata entries. - pub fn count(&self) -> Option