return the_factory;
}
- public int queue (Movie movie, RequestCallback callback) throws Error {
- string path = get_path (movie);
+ public int queue (Movie movie, int width, int height, bool cropped, RequestCallback callback) throws Error {
+ string path = get_poster_path (movie);
- foreach (Request request in requests)
- if (request.movie == movie)
+ foreach (Request request in requests) {
+ if (request.movie == movie &&
+ request.width >= width &&
+ request.height >= height)
return 0;
+ }
- if (FileUtils.test (path, FileTest.IS_REGULAR)) {
- // TODO: make this async?
- var pixbuf = new Gdk.Pixbuf.from_file_at_scale (path, 288, 400, true);
+ // TODO: make this async / put out of process
+ Gdk.Pixbuf pixbuf;
+ if (width <= 256 && height <= 256)
+ pixbuf = request_thumbnail (path, width, height, cropped);
+ else
+ pixbuf = pixbuf_from_path (path, width, height, cropped);
+ if (pixbuf != null) {
callback (pixbuf, movie);
- } else if (server != null && download_posters) {
+ return 0;
+ }
+
+ if (server != null && download_posters) {
var request = new Request ();
- request.handle = server.Fetch (movie.title, movie.year.to_string (), "movie");
+ request.handle = server.Fetch (movie.title, movie.year.to_string (), "movie", width, height);
request.movie = movie;
request.callback = callback;
- request.width = 288;
- request.height = 400;
+ request.width = width;
+ request.height = height;
+ request.cropped = cropped;
requests.append (request);
}
return 0;
}
- public int queue_thumbnail (Movie movie, uint width, uint height, bool cropped, RequestCallback callback) throws Error {
- string path = get_path_thumbnail (movie);
+ private Gdk.Pixbuf? request_thumbnail (string path, int width, int height, bool cropped) {
+ string thumbnail_path = get_thumbnail_path (path, width, height);
- foreach (Request request in requests)
- if (request.movie == movie)
- return 0;
+ var pixbuf = pixbuf_from_path (thumbnail_path, width, height, cropped);
+ if (pixbuf == null) {
+ pixbuf = pixbuf_from_path (path, width, height, cropped);
+ if (pixbuf != null)
+ pixbuf.save (thumbnail_path, "jpeg", null);
+ }
+
+ return pixbuf;
+ }
+ private Gdk.Pixbuf? pixbuf_from_path (string path, int width, int height, bool cropped) {
if (FileUtils.test (path, FileTest.IS_REGULAR)) {
- // TODO: make this async?
- var pixbuf = new Gdk.Pixbuf.from_file_at_scale (path, (int) width, (int) height, true);
+ var pixbuf = new Gdk.Pixbuf.from_file (path);
- callback (pixbuf, movie);
- } else if (server != null && download_posters) {
- var request = new Request ();
+ if (pixbuf.width == width && pixbuf.height == height)
+ return pixbuf;
- request.handle = server.FetchThumbnail (movie.title, movie.year.to_string (), "movie");
- request.movie = movie;
- request.callback = callback;
- request.width = (int) width;
- request.height = (int) height;
- requests.append (request);
+ if (!cropped && (pixbuf.width == width || pixbuf.height == height))
+ return pixbuf;
+
+ if (!download_posters ||
+ (pixbuf.width >= width && pixbuf.height >= height) ||
+ (pixbuf.width >= Poster.SMALL_WIDTH && pixbuf.height >= Poster.SMALL_HEIGHT)) {
+ // Scale to fit
+ return scale_to_fit (pixbuf, width, height, cropped);
+
+ }
+ }
+
+ return null;
+ }
+
+ private Gdk.Pixbuf scale_to_fit (Gdk.Pixbuf source, int width, int height, bool cropped) {
+ Gdk.InterpType interp_type;
+
+ if (width > source.width && height > source.height)
+ interp_type = Gdk.InterpType.HYPER;
+ else
+ interp_type = Gdk.InterpType.BILINEAR;
+
+ if (cropped) {
+ double xscale = (double) width / (double) source.width;
+ double yscale = (double) height / (double) source.height;
+ double scale;
+ int ofs_x = 0;
+ int ofs_y = 0;
+ if (xscale > yscale) {
+ scale = xscale;
+ ofs_y = (int) (height - source.height * scale) / 2;
+ } else {
+ scale = yscale;
+ ofs_x = (int) (width - source.width * scale) / 2;
+ }
+
+ var dest = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8, width, height);
+ source.scale (dest, 0, 0, width, height, ofs_x, ofs_y, scale, scale, interp_type);
+
+ return dest;
+ } else {
+ width = int.min (width,
+ (source.width * height + source.height / 2) / source.height);
+ height = int.min ((source.height * width + source.width / 2) / source.width,
+ height);
+
+ return source.scale_simple (width, height, interp_type);
}
- return 0;
}
private void on_poster_fetched (dynamic DBus.Object server, int handle, string path) {
}
if (request == null)
return;
- try {
- var pixbuf = new Gdk.Pixbuf.from_file_at_size (path, request.width, request.height);
- requests.remove (request);
- request.callback (pixbuf, request.movie);
- return;
- } catch (Error e) {
- warning ("Failed to open poster: %s\n", e.message);
- }
+ var pixbuf = request_thumbnail (path, request.width, request.height, request.cropped);
+
+ requests.remove (request);
+ request.callback (pixbuf, request.movie);
}
private void on_poster_failed (dynamic DBus.Object server, int handle) {
public RequestCallback callback;
public int width;
public int height;
+ public bool cropped;
public void unqueue () {
if (Factory.get_instance ().server != null)
}
public static bool is_cached (Movie movie) {
- string filename = get_path (movie);
+ string filename = get_poster_path (movie);
if (FileUtils.test (filename, FileTest.IS_REGULAR))
return true;
else
return false;
}
- public static string get_path (Movie movie) {
- return Path.build_filename (Environment.get_user_cache_dir (), "media-art", "movie-" +
- Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
- Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
+ public static string get_poster_path (Movie movie) {
+ // return Hildon.albumart_get_path (movie.title, movie.year.to_string (), "movie");
+ return Path.build_filename (Environment.get_user_cache_dir (),
+ "media-art",
+ "movie-%s-%s.jpeg".printf (
+ Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()),
+ Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ())));
}
- public static string get_path_thumbnail (Movie movie) {
- return Path.build_filename (Environment.get_tmp_dir (), "cinaest-thumbnails", "movie-" +
- Checksum.compute_for_string (ChecksumType.MD5, movie.title.down ()) + "-" +
- Checksum.compute_for_string (ChecksumType.MD5, movie.year.to_string ()) + ".jpeg");
+ public static string get_thumbnail_path (string poster_path, int width, int height) {
+ bool large = width > 128 || height > 128;
+
+ return Path.build_filename (Environment.get_home_dir (),
+ ".thumbnails",
+ large ? "large" : "normal",
+ "%s.jpeg".printf (
+ Checksum.compute_for_string (ChecksumType.MD5, "file://" + poster_path)));
}
}