summaryrefslogtreecommitdiff
path: root/src/camera/GPhoto.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera/GPhoto.vala')
-rw-r--r--src/camera/GPhoto.vala83
1 files changed, 40 insertions, 43 deletions
diff --git a/src/camera/GPhoto.vala b/src/camera/GPhoto.vala
index 8dab941..39b2109 100644
--- a/src/camera/GPhoto.vala
+++ b/src/camera/GPhoto.vala
@@ -115,6 +115,22 @@ namespace GPhoto {
return true;
}
+ public Bytes? camera_file_to_bytes (Context context, CameraFile file) {
+ // if buffer can be loaded into memory, return a Bytes class with
+ // CameraFile being the owner of the data. This way, the CameraFile is freed
+ // when the Bytes are freed
+ unowned uint8 *data;
+ ulong data_len;
+ var res = file.get_data_and_size(out data, out data_len);
+ if (res != Result.OK)
+ return null;
+
+ unowned uint8[] buffer = (uint8[]) data;
+ buffer.length = (int) data_len;
+
+ return Bytes.new_with_owner<GPhoto.CameraFile>(buffer, file);
+ }
+
// Libgphoto will in some instances refuse to get metadata from a camera, but the camera is accessible as a
// filesystem. In these cases shotwell can access the file directly. See:
// http://redmine.yorba.org/issues/2959
@@ -146,9 +162,10 @@ namespace GPhoto {
}
public Gdk.Pixbuf? load_preview(Context context, Camera camera, string folder, string filename,
- out uint8[] raw, out size_t raw_length) throws Error {
- raw = null;
- raw_length = 0;
+ out string? preview_md5) throws Error {
+ Bytes? raw = null;
+ Bytes? out_bytes = null;
+ preview_md5 = null;
try {
raw = load_file_into_buffer(context, camera, folder, filename, GPhoto.CameraFileType.PREVIEW);
@@ -158,18 +175,18 @@ namespace GPhoto {
return null;
if(0 == metadata.get_preview_count())
return null;
- PhotoPreview? preview = metadata.get_preview(metadata.get_preview_count() - 1);
+
+ // Get the smallest preview from meta-data
+ var preview = metadata.get_preview (metadata.get_preview_count() - 1);
raw = preview.flatten();
+ preview_md5 = Checksum.compute_for_bytes(ChecksumType.MD5, raw);
}
- if (raw == null) {
- raw_length = 0;
- return null;
- }
-
- raw_length = raw.length;
-
- MemoryInputStream mins = new MemoryInputStream.from_data(raw, null);
+ out_bytes = raw;
+ preview_md5 = Checksum.compute_for_bytes(ChecksumType.MD5, out_bytes);
+
+ MemoryInputStream mins = new MemoryInputStream.from_bytes (raw);
+
return new Gdk.Pixbuf.from_stream_at_scale(mins, ImportPreview.MAX_SCALE, ImportPreview.MAX_SCALE, true, null);
}
@@ -203,7 +220,7 @@ namespace GPhoto {
public PhotoMetadata? load_metadata(Context context, Camera camera, string folder, string filename)
throws Error {
- uint8[] camera_raw = null;
+ Bytes? camera_raw = null;
try {
camera_raw = load_file_into_buffer(context, camera, folder, filename, GPhoto.CameraFileType.EXIF);
} catch {
@@ -233,17 +250,12 @@ namespace GPhoto {
throw new GPhotoError.LIBRARY("[%d] Error retrieving file object for %s/%s: %s",
(int) res, folder, filename, res.as_string());
- // if entire file fits in memory, return a stream from that ... can't merely wrap
- // MemoryInputStream around the camera_file buffer, as that will be destroyed when the
- // function returns
- unowned uint8 *data;
- ulong data_len;
- res = camera_file.get_data_and_size(out data, out data_len);
- if (res == Result.OK) {
- uint8[] buffer = new uint8[data_len];
- Memory.copy(buffer, data, buffer.length);
-
- return new MemoryInputStream.from_data(buffer, on_mins_destroyed);
+ // if entire file fits in memory, return a stream from that ...
+ // The camera_file is set as data on the object to keep it alive while
+ // the MemoryInputStream is alive.
+ var bytes = camera_file_to_bytes (context, camera_file);
+ if (bytes != null) {
+ return new MemoryInputStream.from_bytes(bytes);
}
// if not stored in memory, try copying it to a temp file and then reading out of that
@@ -256,35 +268,20 @@ namespace GPhoto {
return temp.read(null);
}
- private static void on_mins_destroyed(void *data) {
- free(data);
- }
-
// Returns a buffer with the requested file, if within reason. Use load_file for larger files.
- public uint8[]? load_file_into_buffer(Context context, Camera camera, string folder,
+ public Bytes? load_file_into_buffer(Context context, Camera camera, string folder,
string filename, CameraFileType filetype) throws Error {
GPhoto.CameraFile camera_file;
GPhoto.Result res = GPhoto.CameraFile.create(out camera_file);
if (res != Result.OK)
throw new GPhotoError.LIBRARY("[%d] Error allocating camera file: %s", (int) res, res.as_string());
-
+
res = camera.get_file(folder, filename, filetype, camera_file, context);
if (res != Result.OK)
throw new GPhotoError.LIBRARY("[%d] Error retrieving file object for %s/%s: %s",
(int) res, folder, filename, res.as_string());
-
- // if buffer can be loaded into memory, return a copy of that (can't return buffer itself
- // as it will be destroyed when the camera_file is unref'd)
- unowned uint8 *data;
- ulong data_len;
- res = camera_file.get_data_and_size(out data, out data_len);
- if (res != Result.OK)
- return null;
-
- uint8[] buffer = new uint8[data_len];
- Memory.copy(buffer, data, buffer.length);
-
- return buffer;
+
+ return camera_file_to_bytes (context, camera_file);
}
}