diff options
Diffstat (limited to 'src/photos/HeifSupport.vala')
-rw-r--r-- | src/photos/HeifSupport.vala | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/photos/HeifSupport.vala b/src/photos/HeifSupport.vala new file mode 100644 index 0000000..0c05e02 --- /dev/null +++ b/src/photos/HeifSupport.vala @@ -0,0 +1,150 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * + * This software is licensed under the GNU LGPL (version 2.1 or later). + * See the COPYING file in this distribution. + */ + +class HeifFileFormatProperties : PhotoFileFormatProperties { + private static string[] KNOWN_EXTENSIONS = { "heif", "heic" }; + private static string[] KNOWN_MIME_TYPES = { "image/heif" }; + + private static HeifFileFormatProperties instance = null; + + public static void init() { + instance = new HeifFileFormatProperties(); + } + + public static HeifFileFormatProperties get_instance() { + return instance; + } + + public override PhotoFileFormat get_file_format() { + return PhotoFileFormat.HEIF; + } + + public override PhotoFileFormatFlags get_flags() { + return PhotoFileFormatFlags.NONE; + } + + public override string get_user_visible_name() { + return _("HEIF"); + } + + public override string get_default_extension() { + return KNOWN_EXTENSIONS[0]; + } + + public override string[] get_known_extensions() { + return KNOWN_EXTENSIONS; + } + + public override string get_default_mime_type() { + return KNOWN_MIME_TYPES[0]; + } + + public override string[] get_mime_types() { + return KNOWN_MIME_TYPES; + } +} + +public class HeifSniffer : GdkSniffer { + private const string[] MAGIC_SEQUENCES = { "heic", "heix", "hevc", "heim", "heis", "hevm", "hevs", "mif1", "msf1"}; + + public HeifSniffer(File file, PhotoFileSniffer.Options options) { + base (file, options); + } + + public override DetectedPhotoInformation? sniff(out bool is_corrupted) throws Error { + // Rely on GdkSniffer to detect corruption + is_corrupted = false; + + if (!is_supported_bmff_with_variants(file, MAGIC_SEQUENCES)) + return null; + + DetectedPhotoInformation? detected = base.sniff(out is_corrupted); + if (detected == null) + return null; + + if (detected.file_format == PhotoFileFormat.AVIF) + detected.file_format = PhotoFileFormat.HEIF; + + // Heif contains its own rotation information, so we need to ignore the EXIF rotation+ + if (detected.metadata != null) { + detected.metadata.set_orientation(Orientation.TOP_LEFT); + } + + return (detected.file_format == PhotoFileFormat.HEIF) ? detected : null; + } + +} + +public class HeifReader : GdkReader { + public HeifReader(string filepath) { + base (filepath, PhotoFileFormat.HEIF); + } + + public override PhotoMetadata read_metadata() throws Error { + PhotoMetadata metadata = new PhotoMetadata(); + metadata.read_from_file(get_file()); + // Heif contains its own rotation information, so we need to ignore the EXIF rotation + metadata.set_orientation(Orientation.TOP_LEFT); + return metadata; + } + +} + +public class HeifMetadataWriter : PhotoFileMetadataWriter { + public HeifMetadataWriter(string filepath) { + base (filepath, PhotoFileFormat.HEIF); + } + + public override void write_metadata(PhotoMetadata metadata) throws Error { + metadata.write_to_file(get_file()); + } +} + +public class HeifFileFormatDriver : PhotoFileFormatDriver { + private static HeifFileFormatDriver instance = null; + + public static void init() { + instance = new HeifFileFormatDriver(); + HeifFileFormatProperties.init(); + } + + public static HeifFileFormatDriver get_instance() { + return instance; + } + + public override PhotoFileFormatProperties get_properties() { + return HeifFileFormatProperties.get_instance(); + } + + public override PhotoFileReader create_reader(string filepath) { + return new HeifReader(filepath); + } + + public override bool can_write_image() { + return false; + } + + public override bool can_write_metadata() { + return true; + } + + public override PhotoFileWriter? create_writer(string filepath) { + return null; + } + + public override PhotoFileMetadataWriter? create_metadata_writer(string filepath) { + return new HeifMetadataWriter(filepath); + } + + public override PhotoFileSniffer create_sniffer(File file, PhotoFileSniffer.Options options) { + return new HeifSniffer(file, options); + } + + public override PhotoMetadata create_metadata() { + return new PhotoMetadata(); + } +} + |