summaryrefslogtreecommitdiff
path: root/src/photos/JpegXLSupport.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/photos/JpegXLSupport.vala')
-rw-r--r--src/photos/JpegXLSupport.vala149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/photos/JpegXLSupport.vala b/src/photos/JpegXLSupport.vala
new file mode 100644
index 0000000..eed220c
--- /dev/null
+++ b/src/photos/JpegXLSupport.vala
@@ -0,0 +1,149 @@
+/* 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 JpegXLFileFormatProperties : PhotoFileFormatProperties {
+ private static string[] KNOWN_EXTENSIONS = { "jxl", "jpegxl" };
+ private static string[] KNOWN_MIME_TYPES = { "image/jxl" };
+
+ private static JpegXLFileFormatProperties instance = null;
+
+ public static void init() {
+ instance = new JpegXLFileFormatProperties();
+ }
+
+ public static JpegXLFileFormatProperties get_instance() {
+ return instance;
+ }
+
+ public override PhotoFileFormat get_file_format() {
+ return PhotoFileFormat.JPEGXL;
+ }
+
+ public override PhotoFileFormatFlags get_flags() {
+ return PhotoFileFormatFlags.NONE;
+ }
+
+ public override string get_user_visible_name() {
+ return _("JPEGXL");
+ }
+
+ 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 JpegXLSniffer : GdkSniffer {
+ // See https://github.com/ImageMagick/jpeg-xl/blob/main/doc/format_overview.md#file-format
+ private const uint8[] CODESTREAM_MAGIC_SEQUENCE = { 0xff, 0x0a };
+ private const uint8[] BMFF_MAGIC_SEQUENCE = {0x00, 0x00, 0x00, 0x0C, 0x4A, 0x58, 0x4C, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
+
+
+ public JpegXLSniffer(File file, PhotoFileSniffer.Options options) {
+ base (file, options);
+ }
+
+ private static bool is_jpegxl_file(File file) throws Error {
+ FileInputStream instream = file.read(null);
+
+ // Read out first four bytes
+ uint8[] file_lead_sequence = new uint8[BMFF_MAGIC_SEQUENCE.length];
+
+ var size = instream.read(file_lead_sequence, null);
+
+ return size == BMFF_MAGIC_SEQUENCE.length && (Memory.cmp(CODESTREAM_MAGIC_SEQUENCE, file_lead_sequence, CODESTREAM_MAGIC_SEQUENCE.length) == 0 ||
+ Memory.cmp(BMFF_MAGIC_SEQUENCE, file_lead_sequence, BMFF_MAGIC_SEQUENCE.length) == 0);
+
+ }
+
+ public override DetectedPhotoInformation? sniff(out bool is_corrupted) throws Error {
+ // Rely on GdkSniffer to detect corruption
+ is_corrupted = false;
+
+ if (!is_jpegxl_file(file))
+ return null;
+
+ DetectedPhotoInformation? detected = base.sniff(out is_corrupted);
+ if (detected == null)
+ return null;
+
+ return (detected.file_format == PhotoFileFormat.JPEGXL) ? detected : null;
+ }
+
+}
+
+public class JpegXLReader : GdkReader {
+ public JpegXLReader(string filepath) {
+ base (filepath, PhotoFileFormat.JPEGXL);
+ }
+}
+
+public class JpegXLMetadataWriter : PhotoFileMetadataWriter {
+ public JpegXLMetadataWriter(string filepath) {
+ base (filepath, PhotoFileFormat.JPEGXL);
+ }
+
+ public override void write_metadata(PhotoMetadata metadata) throws Error {
+ metadata.write_to_file(get_file());
+ }
+}
+
+public class JpegXLFileFormatDriver : PhotoFileFormatDriver {
+ private static JpegXLFileFormatDriver instance = null;
+
+ public static void init() {
+ instance = new JpegXLFileFormatDriver();
+ JpegXLFileFormatProperties.init();
+ }
+
+ public static JpegXLFileFormatDriver get_instance() {
+ return instance;
+ }
+
+ public override PhotoFileFormatProperties get_properties() {
+ return JpegXLFileFormatProperties.get_instance();
+ }
+
+ public override PhotoFileReader create_reader(string filepath) {
+ return new JpegXLReader(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 JpegXLMetadataWriter(filepath);
+ }
+
+ public override PhotoFileSniffer create_sniffer(File file, PhotoFileSniffer.Options options) {
+ return new JpegXLSniffer(file, options);
+ }
+
+ public override PhotoMetadata create_metadata() {
+ return new PhotoMetadata();
+ }
+}
+