using MetadataExtractor; using MetadataExtractor.Formats.Exif.Makernotes; using System.Globalization; using Phares.Shared.Models; using Phares.Shared.Models.Stateless; namespace Phares.Metadata.Models.Stateless; internal abstract class Exif { private static DateTime? GetDateTime(string? value) { DateTime? result; string dateTimeFormat = "yyyy:MM:dd HH:mm:ss"; string alternateFormat = "ddd MMM dd HH:mm:ss yyyy"; if (value is not null && DateTime.TryParse(value, out DateTime dateTime)) result = dateTime; else if (value is not null && value.Length == dateTimeFormat.Length && DateTime.TryParseExact(value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) result = dateTime; else if (value is not null && value.Length == alternateFormat.Length && DateTime.TryParseExact(value, alternateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) result = dateTime; else result = null; return result; } private static AviDirectory[] GetAviDirectories(IReadOnlyList directories) { List results = []; AviDirectory aviDirectory; IEnumerable aviDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Avi.AviDirectory a in aviDirectories) { if (a.Tags.Count == 0) continue; DateTime? dateTimeOriginal; string? duration = a.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagDuration); string? height = a.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagHeight); string? width = a.GetDescription(MetadataExtractor.Formats.Avi.AviDirectory.TagWidth); if (a.TryGetDateTime(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal, out DateTime checkDateTime)) dateTimeOriginal = checkDateTime; else dateTimeOriginal = GetDateTime(a.GetString(MetadataExtractor.Formats.Avi.AviDirectory.TagDateTimeOriginal)); if (dateTimeOriginal is null && duration is null && height is null && width is null) continue; aviDirectory = new(DateTimeOriginal: dateTimeOriginal, Duration: duration, Height: height, Width: width); results.Add(aviDirectory); } return results.ToArray(); } private static ExifDirectoryBase[] GetExifBaseDirectories(IReadOnlyList directories) { List results = []; ExifDirectoryBase exifDirectoryBase; IEnumerable exifBaseDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Exif.ExifDirectoryBase e in exifBaseDirectories) { if (e.Tags.Count == 0) continue; DateTime? dateTime; DateTime checkDateTime; DateTime? dateTimeOriginal; DateTime? dateTimeDigitized; string? aperture = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagAperture); string? applicationNotes = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagApplicationNotes); string? artist = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagArtist); string? bitsPerSample = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagBitsPerSample); string? bodySerialNumber = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagBodySerialNumber); string? cameraOwnerName = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagCameraOwnerName); string? compressedAverageBitsPerPixel = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagCompressedAverageBitsPerPixel); string? compression = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagCompression); string? copyright = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagCopyright); string? documentName = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDocumentName); string? exifVersion = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagExifVersion); string? exposureTime = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagExposureTime); string? fileSource = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagFileSource); string? imageDescription = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageDescription); string? imageHeight = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageHeight); int? imageHeightValue = imageHeight is null ? null : e.GetInt32(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageHeight); string? imageNumber = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageNumber); string? imageUniqueId = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageUniqueId); string? imageWidth = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageWidth); int? imageWidthValue = imageWidth is null ? null : e.GetInt32(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageWidth); string? isoSpeed = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagIsoSpeed); string? lensMake = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagLensMake); string? lensModel = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagLensModel); string? lensSerialNumber = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagLensSerialNumber); string? make = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagMake); string? makerNote = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagMakernote); string? model = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagModel); string? orientation = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation); int? orientationValue = orientation is null ? null : e.GetInt32(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation); string? rating = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagRating); string? ratingPercent = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagRatingPercent); string? securityClassification = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagSecurityClassification); string? shutterSpeed = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagShutterSpeed); string? software = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagSoftware); string? timeZone = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagTimeZone); string? timeZoneDigitized = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagTimeZoneDigitized); string? timeZoneOriginal = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagTimeZoneOriginal); string? userComment = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagUserComment); string? winAuthor = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinAuthor); string? winComment = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinComment); string? winKeywords = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinKeywords); string? winSubject = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinSubject); string? winTitle = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagWinTitle); string? xResolution = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagXResolution); string? yResolution = e.GetDescription(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagYResolution); if (e.TryGetDateTime(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime, out checkDateTime)) dateTime = checkDateTime; else dateTime = GetDateTime(e.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTime)); if (e.TryGetDateTime(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal, out checkDateTime)) dateTimeOriginal = checkDateTime; else dateTimeOriginal = GetDateTime(e.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeOriginal)); if (e.TryGetDateTime(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeDigitized, out checkDateTime)) dateTimeDigitized = checkDateTime; else dateTimeDigitized = GetDateTime(e.GetString(MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeDigitized)); if (userComment is not null && userComment.Length > 255) userComment = "..."; if (aperture is null && applicationNotes is null && artist is null && bitsPerSample is null && bodySerialNumber is null && cameraOwnerName is null && compressedAverageBitsPerPixel is null && compression is null && copyright is null && dateTime is null && dateTimeDigitized is null && dateTimeOriginal is null && documentName is null && exifVersion is null && exposureTime is null && fileSource is null && imageDescription is null && imageHeight is null && imageNumber is null && imageUniqueId is null && imageWidth is null && isoSpeed is null && lensMake is null && lensModel is null && lensSerialNumber is null && make is null && makerNote is null && model is null && orientation is null && orientationValue is null && rating is null && ratingPercent is null && securityClassification is null && shutterSpeed is null && software is null && timeZone is null && timeZoneDigitized is null && timeZoneOriginal is null && userComment is null && winAuthor is null && winComment is null && winKeywords is null && winSubject is null && winTitle is null && xResolution is not null && yResolution is null) continue; exifDirectoryBase = new(Aperture: aperture, ApplicationNotes: applicationNotes, Artist: artist, BitsPerSample: bitsPerSample, BodySerialNumber: bodySerialNumber, CameraOwnerName: cameraOwnerName, CompressedAverageBitsPerPixel: compressedAverageBitsPerPixel, Compression: compression, Copyright: copyright, DateTime: dateTime, DateTimeDigitized: dateTimeDigitized, DateTimeOriginal: dateTimeOriginal, DocumentName: documentName, ExifVersion: exifVersion, ExposureTime: exposureTime, FileSource: fileSource, ImageDescription: imageDescription, ImageHeight: imageHeight, ImageHeightValue: imageHeightValue, ImageNumber: imageNumber, ImageUniqueId: imageUniqueId, ImageWidth: imageWidth, ImageWidthValue: imageWidthValue, IsoSpeed: isoSpeed, LensMake: lensMake, LensModel: lensModel, LensSerialNumber: lensSerialNumber, Make: make, MakerNote: makerNote, Model: model, Orientation: orientation, OrientationValue: orientationValue, Rating: rating, RatingPercent: ratingPercent, SecurityClassification: securityClassification, ShutterSpeed: shutterSpeed, Software: software, TimeZone: timeZone, TimeZoneDigitized: timeZoneDigitized, TimeZoneOriginal: timeZoneOriginal, UserComment: userComment, WinAuthor: winAuthor, WinComment: winComment, WinKeywords: winKeywords, WinSubject: winSubject, WinTitle: winTitle, XResolution: xResolution, YResolution: yResolution); results.Add(exifDirectoryBase); } return results.ToArray(); } private static FileMetadataDirectory[] GetFileMetadataDirectories(string file, IReadOnlyList directories) { List results = []; FileMetadataDirectory fileMetadataDirectory; IEnumerable fileMetadataDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.FileSystem.FileMetadataDirectory f in fileMetadataDirectories) { if (f.Tags.Count == 0) continue; DateTime? fileModifiedDate; string? fileName = f.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileName); string? fileSize = f.GetDescription(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileSize); if (f.TryGetDateTime(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate, out DateTime checkDateTime)) fileModifiedDate = checkDateTime; else fileModifiedDate = GetDateTime(f.GetString(MetadataExtractor.Formats.FileSystem.FileMetadataDirectory.TagFileModifiedDate)); if (fileName is null || !file.EndsWith(fileName)) throw new NotSupportedException($"!{file}.EndsWith({fileName})"); if (fileModifiedDate is null && fileName is null && fileSize is null) continue; fileMetadataDirectory = new(FileModifiedDate: fileModifiedDate, FileName: fileName, FileSize: fileSize); results.Add(fileMetadataDirectory); } return results.ToArray(); } private static GifHeaderDirectory[] GetGifHeaderDirectories(IReadOnlyList directories) { List results = []; GifHeaderDirectory gifHeaderDirectory; IEnumerable gifHeaderDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Gif.GifHeaderDirectory g in gifHeaderDirectories) { if (g.Tags.Count == 0) continue; string? imageHeight = g.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageHeight); string? imageWidth = g.GetDescription(MetadataExtractor.Formats.Gif.GifHeaderDirectory.TagImageWidth); if (imageHeight is null && imageWidth is null) continue; gifHeaderDirectory = new(ImageHeight: imageHeight, ImageWidth: imageWidth); results.Add(gifHeaderDirectory); } return results.ToArray(); } private static GpsDirectory[] GetGpsDirectories(IReadOnlyList directories) { List results = []; GpsDirectory gpsDirectory; IEnumerable gpsDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Exif.GpsDirectory g in gpsDirectories) { if (g.Tags.Count == 0) continue; DateTime? timeStamp; string? altitude = g.GetDescription(MetadataExtractor.Formats.Exif.GpsDirectory.TagAltitude); string? latitude = g.GetDescription(MetadataExtractor.Formats.Exif.GpsDirectory.TagLatitude); string? latitudeRef = g.GetDescription(MetadataExtractor.Formats.Exif.GpsDirectory.TagLatitudeRef); string? longitude = g.GetDescription(MetadataExtractor.Formats.Exif.GpsDirectory.TagLongitude); string? longitudeRef = g.GetDescription(MetadataExtractor.Formats.Exif.GpsDirectory.TagLongitudeRef); if (g.TryGetDateTime(MetadataExtractor.Formats.Exif.GpsDirectory.TagTimeStamp, out DateTime checkDateTime)) timeStamp = checkDateTime; else timeStamp = GetDateTime(g.GetString(MetadataExtractor.Formats.Exif.GpsDirectory.TagTimeStamp)); if (altitude is null && latitude is null && latitudeRef is null && longitude is null && longitudeRef is null && timeStamp is null) continue; gpsDirectory = new(Altitude: altitude, Latitude: latitude, LatitudeRef: latitudeRef, Longitude: longitude, LongitudeRef: longitudeRef, TimeStamp: timeStamp); results.Add(gpsDirectory); } return results.ToArray(); } private static JpegDirectory[] GetJpegDirectories(IReadOnlyList directories) { List results = []; JpegDirectory jpegDirectory; IEnumerable jpegDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Jpeg.JpegDirectory j in jpegDirectories) { if (j.Tags.Count == 0) continue; string? imageHeight = j.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageHeight); string? imageWidth = j.GetDescription(MetadataExtractor.Formats.Jpeg.JpegDirectory.TagImageWidth); if (imageHeight is null && imageWidth is null) continue; jpegDirectory = new(ImageHeight: imageHeight, ImageWidth: imageWidth); results.Add(jpegDirectory); } return results.ToArray(); } private static MakernoteDirectory[] GetMakernoteDirectories(IReadOnlyList directories) { List results = []; MakernoteDirectory makernoteDirectory; IEnumerable appleMakernoteDirectories = directories.OfType(); foreach (AppleMakernoteDirectory appleMakernoteDirectory in appleMakernoteDirectories) { if (appleMakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = null; string? firmwareVersion = null; string? qualityAndFileFormat = null; if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable canonMakernoteDirectories = directories.OfType(); foreach (CanonMakernoteDirectory canonMakernoteDirectory in canonMakernoteDirectories) { if (canonMakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.TagModelId); string? firmwareVersion = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.TagCanonFirmwareVersion); string? qualityAndFileFormat = canonMakernoteDirectory.GetDescription(CanonMakernoteDirectory.CameraSettings.TagQuality); if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable nikonType2MakernoteDirectories = directories.OfType(); foreach (NikonType2MakernoteDirectory nikonType2MakernoteDirectory in nikonType2MakernoteDirectories) { if (nikonType2MakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagCameraSerialNumber); string? firmwareVersion = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagFirmwareVersion); string? qualityAndFileFormat = nikonType2MakernoteDirectory.GetDescription(NikonType2MakernoteDirectory.TagQualityAndFileFormat); if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable olympusMakernoteDirectories = directories.OfType(); foreach (OlympusMakernoteDirectory olympusMakernoteDirectory in olympusMakernoteDirectories) { if (olympusMakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagSerialNumber1); string? firmwareVersion = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagBodyFirmwareVersion); string? qualityAndFileFormat = olympusMakernoteDirectory.GetDescription(OlympusMakernoteDirectory.TagJpegQuality); if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable panasonicMakernoteDirectories = directories.OfType(); foreach (PanasonicMakernoteDirectory panasonicMakernoteDirectory in panasonicMakernoteDirectories) { if (panasonicMakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagInternalSerialNumber); string? firmwareVersion = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagFirmwareVersion); string? qualityAndFileFormat = panasonicMakernoteDirectory.GetDescription(PanasonicMakernoteDirectory.TagQualityMode); if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable samsungType2MakernoteDirectories = directories.OfType(); foreach (SamsungType2MakernoteDirectory samsungType2MakernoteDirectory in samsungType2MakernoteDirectories) { if (samsungType2MakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = samsungType2MakernoteDirectory.GetDescription(SamsungType2MakernoteDirectory.TagSerialNumber); string? firmwareVersion = samsungType2MakernoteDirectory.GetDescription(SamsungType2MakernoteDirectory.TagFirmwareName); string? qualityAndFileFormat = null; if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(cameraSerialNumber, firmwareVersion, qualityAndFileFormat); results.Add(makernoteDirectory); } IEnumerable sonyType6MakernoteDirectories = directories.OfType(); foreach (SonyType6MakernoteDirectory sonyType6MakernoteDirectory in sonyType6MakernoteDirectories) { if (sonyType6MakernoteDirectory.Tags.Count == 0) continue; string? cameraSerialNumber = null; string? firmwareVersion = null; string? qualityAndFileFormat = null; if (cameraSerialNumber is null && firmwareVersion is null && qualityAndFileFormat is null) continue; makernoteDirectory = new(CameraSerialNumber: cameraSerialNumber, FirmwareVersion: firmwareVersion, QualityAndFileFormat: qualityAndFileFormat); results.Add(makernoteDirectory); } return results.ToArray(); } private static PhotoshopDirectory[] GetPhotoshopDirectories(IReadOnlyList directories) { List results = []; PhotoshopDirectory photoshopDirectory; IEnumerable photoshopDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Photoshop.PhotoshopDirectory p in photoshopDirectories) { if (p.Tags.Count == 0) continue; string? jpegQuality = p.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagJpegQuality); string? url = p.GetDescription(MetadataExtractor.Formats.Photoshop.PhotoshopDirectory.TagUrl); if (jpegQuality is null && url is null) continue; photoshopDirectory = new(JpegQuality: jpegQuality, Url: url); results.Add(photoshopDirectory); } return results.ToArray(); } private static PngDirectory[] GetPngDirectories(IReadOnlyList directories) { List results = []; PngDirectory pngDirectory; IEnumerable pngDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.Png.PngDirectory p in pngDirectories) { if (p.Tags.Count == 0) continue; string? imageHeight = p.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageHeight); string? imageWidth = p.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagImageWidth); string? textualData = p.GetDescription(MetadataExtractor.Formats.Png.PngDirectory.TagTextualData); if (imageHeight is null && imageWidth is null && textualData is null) continue; pngDirectory = new(ImageHeight: imageHeight, ImageWidth: imageWidth, TextualData: textualData); results.Add(pngDirectory); } return results.ToArray(); } private static QuickTimeMovieHeaderDirectory[] GetQuickTimeMovieHeaderDirectoryDirectories(IReadOnlyList directories) { List results = []; QuickTimeMovieHeaderDirectory quickTimeMovieHeaderDirectory; IEnumerable quickTimeMovieHeaderDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory q in quickTimeMovieHeaderDirectories) { if (q.Tags.Count == 0) continue; DateTime? created; if (q.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated, out DateTime checkDateTime)) created = checkDateTime; else created = GetDateTime(q.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeMovieHeaderDirectory.TagCreated)); if (created is null) continue; quickTimeMovieHeaderDirectory = new(Created: created); results.Add(quickTimeMovieHeaderDirectory); } return results.ToArray(); } private static QuickTimeTrackHeaderDirectory[] GetQuickTimeTrackHeaderDirectoryDirectories(IReadOnlyList directories) { List results = []; QuickTimeTrackHeaderDirectory quickTimeTrackHeaderDirectory; IEnumerable quickTimeTrackHeaderDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory q in quickTimeTrackHeaderDirectories) { if (q.Tags.Count == 0) continue; DateTime? created; if (q.TryGetDateTime(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated, out DateTime checkDateTime)) created = checkDateTime; else created = GetDateTime(q.GetString(MetadataExtractor.Formats.QuickTime.QuickTimeTrackHeaderDirectory.TagCreated)); if (created is null) continue; quickTimeTrackHeaderDirectory = new(Created: created); results.Add(quickTimeTrackHeaderDirectory); } return results.ToArray(); } private static WebPDirectory[] GetWebPDirectories(IReadOnlyList directories) { List results = []; WebPDirectory webPDirectory; IEnumerable webPDirectories = directories.OfType(); foreach (MetadataExtractor.Formats.WebP.WebPDirectory w in webPDirectories) { if (w.Tags.Count == 0) continue; string? imageHeight = w.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageHeight); string? imageWidth = w.GetDescription(MetadataExtractor.Formats.WebP.WebPDirectory.TagImageWidth); if (imageHeight is null && imageWidth is null) continue; webPDirectory = new(ImageHeight: imageHeight, ImageWidth: imageWidth); results.Add(webPDirectory); } return results.ToArray(); } private static ExifDirectory Covert(FilePath filePath, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? personKeyFormattedAndKeyTicksAndDisplayDirectoryName, IReadOnlyList directories, System.Drawing.Size? size) { ExifDirectory result; AviDirectory[] aviDirectories = GetAviDirectories(directories); GpsDirectory[] gpsDirectories = GetGpsDirectories(directories); PngDirectory[] pngDirectories = GetPngDirectories(directories); JpegDirectory[] jpegDirectories = GetJpegDirectories(directories); WebPDirectory[] webPDirectories = GetWebPDirectories(directories); ExifDirectoryBase[] exifBaseDirectories = GetExifBaseDirectories(directories); GifHeaderDirectory[] gifHeaderDirectories = GetGifHeaderDirectories(directories); MakernoteDirectory[] makernoteDirectories = GetMakernoteDirectories(directories); PhotoshopDirectory[] photoshopDirectories = GetPhotoshopDirectories(directories); FileMetadataDirectory[] fileMetadataDirectories = GetFileMetadataDirectories(filePath.FullName, directories); QuickTimeMovieHeaderDirectory[] quickTimeMovieHeaderDirectories = GetQuickTimeMovieHeaderDirectoryDirectories(directories); QuickTimeTrackHeaderDirectory[] quickTimeTrackHeaderDirectories = GetQuickTimeTrackHeaderDirectoryDirectories(directories); result = new(AviDirectories: aviDirectories, ExifBaseDirectories: exifBaseDirectories, FileMetadataDirectories: fileMetadataDirectories, FilePath: filePath, GifHeaderDirectories: gifHeaderDirectories, GpsDirectories: gpsDirectories, Height: size?.Height ?? IMetaBase.GetHeight(exifBaseDirectories), JpegDirectories: jpegDirectories, MakernoteDirectories: makernoteDirectories, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName: personKeyFormattedAndKeyTicksAndDisplayDirectoryName, PhotoshopDirectories: photoshopDirectories, PngDirectories: pngDirectories, QuickTimeMovieHeaderDirectories: quickTimeMovieHeaderDirectories, QuickTimeTrackHeaderDirectories: quickTimeTrackHeaderDirectories, WebPDirectories: webPDirectories, Width: size?.Width ?? IMetaBase.GetWidth(exifBaseDirectories)); return result; } internal static ExifDirectory GetExifDirectory(FilePath filePath, Stream stream, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? personKeyFormattedAndKeyTicksAndDisplayDirectoryName) { ExifDirectory result; IReadOnlyList directories = ImageMetadataReader.ReadMetadata(stream); System.Drawing.Size? size; try { size = Dimensions.GetDimensions(stream); } catch (Exception) { size = null; } result = Covert(filePath, personKeyFormattedAndKeyTicksAndDisplayDirectoryName, directories, size); return result; } internal static ExifDirectory? GetExifDirectory(ResultSettings resultSettings, MetadataSettings metadataSettings, FileInfo fileInfo) { ExifDirectory? result; FileHolder fileHolder = FileHolder.Get(fileInfo, id: null); const PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName? p = null; FilePath filePath = FilePath.Get(resultSettings, metadataSettings, fileHolder, index: fileHolder.Id); using Stream stream = File.OpenRead(filePath.FullName); result = GetExifDirectory(filePath, stream, p); return result; } }