diff options
Diffstat (limited to 'src/photos/PhotoMetadata.vala')
-rw-r--r-- | src/photos/PhotoMetadata.vala | 92 |
1 files changed, 53 insertions, 39 deletions
diff --git a/src/photos/PhotoMetadata.vala b/src/photos/PhotoMetadata.vala index e9a9042..2c2d6c5 100644 --- a/src/photos/PhotoMetadata.vala +++ b/src/photos/PhotoMetadata.vala @@ -190,16 +190,16 @@ public abstract class PhotoPreview { return extension; } - public abstract uint8[] flatten() throws Error; + public abstract Bytes flatten() throws Error; public virtual Gdk.Pixbuf? get_pixbuf() throws Error { - uint8[] flattened = flatten(); + var flattened = flatten(); // Need to create from stream or file for decode ... catch decode error and return null, // different from an I/O error causing the problem try { - return new Gdk.Pixbuf.from_stream(new MemoryInputStream.from_data(flattened, null), - null); + return new Gdk.Pixbuf.from_stream(new + MemoryInputStream.from_bytes(flattened)); } catch (Error err) { warning("Unable to decode thumbnail for %s: %s", name, err.message); @@ -236,17 +236,20 @@ public class PhotoMetadata : MediaMetadata { this.number = number; } - public override uint8[] flatten() throws Error { + public override Bytes flatten() throws Error { unowned GExiv2.PreviewProperties?[] props = owner.exiv2.get_preview_properties(); assert(props != null && props.length > number); - return owner.exiv2.get_preview_image(props[number]).get_data(); + return new + Bytes(owner.exiv2.get_preview_image(props[number]).get_data()); } } private GExiv2.Metadata exiv2 = new GExiv2.Metadata(); private Exif.Data? exif = null; string source_name = "<uninitialized>"; + private string? metadata_hash = null; + private string? thumbnail_md5 = null; public PhotoMetadata() { } @@ -278,18 +281,13 @@ public class PhotoMetadata : MediaMetadata { source_name = "<memory buffer %d bytes>".printf(length); } - public void read_from_app1_segment(uint8[] buffer, int length = 0) throws Error { - if (length <= 0) - length = buffer.length; - - assert(buffer.length >= length); - + public void read_from_app1_segment(Bytes buffer) throws Error { exiv2 = new GExiv2.Metadata(); exif = null; - exiv2.from_app1_segment(buffer, length); - exif = Exif.Data.new_from_data(buffer, length); - source_name = "<app1 segment %d bytes>".printf(length); + exiv2.from_app1_segment(buffer.get_data(), (long) buffer.get_size()); + exif = Exif.Data.new_from_data(buffer.get_data(), buffer.get_size()); + source_name = "<app1 segment %zu bytes>".printf(buffer.get_size()); } public static MetadataDomain get_tag_domain(string tag) { @@ -691,43 +689,59 @@ public class PhotoMetadata : MediaMetadata { } // Returns raw bytes of EXIF metadata, including signature and optionally the preview (if present). - public uint8[]? flatten_exif(bool include_preview) { + public string? exif_hash() { if (exif == null) return null; - - // save thumbnail to strip if no attachments requested (so it can be added back and - // deallocated automatically) - uchar *thumbnail = exif.data; - uint thumbnail_size = exif.size; - if (!include_preview) { - exif.data = null; - exif.size = 0; + + if (this.metadata_hash != null) { + return this.metadata_hash; } - - uint8[]? flattened = null; - - // save the struct to a buffer and copy into a Vala-friendly one + + string? hash = null; + + var thumb = exif.data; + var thumb_size = exif.size; + + // Strip potential thumbnail + exif.data = null; + exif.size = 0; + uchar *saved_data = null; uint saved_size = 0; + exif.save_data(&saved_data, &saved_size); + + exif.data = thumb; + exif.size = thumb_size; + if (saved_size > 0 && saved_data != null) { - flattened = new uint8[saved_size]; - Memory.copy(flattened, saved_data, saved_size); - + var md5 = new Checksum(ChecksumType.MD5); + md5.update((uchar []) saved_data, saved_size); Exif.Mem.new_default().free(saved_data); + + this.metadata_hash = md5.get_string (); } - - // restore thumbnail (this works in either case) - exif.data = thumbnail; - exif.size = thumbnail_size; - - return flattened; + + return hash; } // Returns raw bytes of EXIF preview, if present - public uint8[]? flatten_exif_preview() { + public string? thumbnail_hash() { + if (this.thumbnail_md5 != null) { + return this.thumbnail_md5; + } + uchar[] buffer; - return exiv2.get_exif_thumbnail(out buffer) ? buffer : null; + if (exiv2.get_exif_thumbnail(out buffer)) { + var md5 = new Checksum(ChecksumType.MD5); + md5.update(buffer, buffer.length); + + this.thumbnail_md5 = md5.get_string(); + + return this.thumbnail_md5; + } + + return null; } public uint get_preview_count() { |