// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #pragma once #include "MetadataTypes.h" #include "MetadataResultCache.h" #include "PropVariantValue.h" #include #include // Forward declarations for unit test friend classes namespace WICMetadataExtractorTests { class ExtractAVIFMetadataTests; } namespace PowerRenameLib { /// /// Metadata path format based on container type /// enum class MetadataPathFormat { JPEG, // Uses /app1/ifd/... paths (JPEG) IFD // Uses /ifd/... paths (HEIF, TIFF, etc.) }; /// /// Windows Imaging Component (WIC) implementation for metadata extraction /// Provides efficient batch extraction of all metadata types with built-in caching /// class WICMetadataExtractor { // Friend declarations for unit testing friend class WICMetadataExtractorTests::ExtractAVIFMetadataTests; public: WICMetadataExtractor(); ~WICMetadataExtractor(); // Public metadata extraction methods bool ExtractEXIFMetadata( const std::wstring& filePath, EXIFMetadata& outMetadata); bool ExtractXMPMetadata( const std::wstring& filePath, XMPMetadata& outMetadata); void ClearCache(); private: // WIC factory management static CComPtr GetWICFactory(); static void InitializeWIC(); // WIC operations CComPtr CreateDecoder(const std::wstring& filePath); CComPtr GetMetadataReader(IWICBitmapDecoder* decoder); bool LoadEXIFMetadata(const std::wstring& filePath, EXIFMetadata& outMetadata); bool LoadXMPMetadata(const std::wstring& filePath, XMPMetadata& outMetadata); // Batch extraction methods void ExtractAllEXIFFields(IWICMetadataQueryReader* reader, EXIFMetadata& metadata, MetadataPathFormat pathFormat); void ExtractGPSData(IWICMetadataQueryReader* reader, EXIFMetadata& metadata, MetadataPathFormat pathFormat); void ExtractAllXMPFields(IWICMetadataQueryReader* reader, XMPMetadata& metadata); // Internal container format detection MetadataPathFormat GetMetadataPathFormatFromDecoder(IWICBitmapDecoder* decoder); // Field reading helpers std::optional ReadDateTime(IWICMetadataQueryReader* reader, const std::wstring& path); std::optional ReadString(IWICMetadataQueryReader* reader, const std::wstring& path); std::optional ReadInteger(IWICMetadataQueryReader* reader, const std::wstring& path); std::optional ReadDouble(IWICMetadataQueryReader* reader, const std::wstring& path); // Helper methods std::optional ReadMetadata(IWICMetadataQueryReader* reader, const std::wstring& path); private: MetadataResultCache cache; }; }