/** * as_screenshot_get_image_for_locale: * @screenshot: a #AsScreenshot instance. * @locale: locale, or %NULL * @width: target width * @height: target height * * Gets the AsImage closest to the target size with the specified locale. * The #AsImage may not actually be the requested size, and the application may * have to pad / rescale the image to make it fit. * * FIXME: This function assumes the images are ordered in preference order, e.g. * "en_GB -> en -> NULL" * * Returns: (transfer none): an #AsImage, or %NULL * * Since: 0.5.14 **/ AsImage * as_screenshot_get_image_for_locale (AsScreenshot *screenshot, const gchar *locale, guint width, guint height) { AsImage *im; AsImage *im_best = NULL; AsScreenshotPrivate *priv = GET_PRIVATE (screenshot); gint64 best_size = G_MAXINT64; guint i; gint64 tmp; g_return_val_if_fail (AS_IS_SCREENSHOT (screenshot), NULL); for (i = 0; i < priv->images->len; i++) { im = g_ptr_array_index (priv->images, i); if (!as_utils_locale_is_compatible (as_image_get_locale (im), locale)) continue; tmp = ABS ((gint64) (width * height) - (gint64) (as_image_get_width (im) * as_image_get_height (im))); if (tmp < best_size) { best_size = tmp; im_best = im; } } return im_best; }
/** * gs_appstream_are_screenshots_perfect: */ static gboolean gs_appstream_are_screenshots_perfect (AsApp *app) { AsImage *image; AsScreenshot *screenshot; GPtrArray *screenshots; guint height; guint i; guint width; screenshots = as_app_get_screenshots (app); if (screenshots->len == 0) return FALSE; for (i = 0; i < screenshots->len; i++) { /* get the source image as the thumbs will be resized & padded */ screenshot = g_ptr_array_index (screenshots, i); image = as_screenshot_get_source (screenshot); if (image == NULL) return FALSE; width = as_image_get_width (image); height = as_image_get_height (image); /* too small */ if (width < AS_IMAGE_LARGE_WIDTH || height < AS_IMAGE_LARGE_HEIGHT) return FALSE; /* too large */ if (width > AS_IMAGE_LARGE_WIDTH * 2 || height > AS_IMAGE_LARGE_HEIGHT * 2) return FALSE; /* not 16:9 */ if ((width / 16) * 9 != height) return FALSE; } return TRUE; }
static gboolean ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) { AsImageAlphaFlags alpha_flags; const gchar *url; gboolean require_correct_aspect_ratio = FALSE; gdouble desired_aspect = 1.777777778; gdouble screenshot_aspect; guint status_code; guint screenshot_height; guint screenshot_width; guint ss_size_height_max = 900; guint ss_size_height_min = 351; guint ss_size_width_max = 1600; guint ss_size_width_min = 624; g_autoptr(GdkPixbuf) pixbuf = NULL; g_autoptr(GInputStream) stream = NULL; g_autoptr(SoupMessage) msg = NULL; g_autoptr(SoupURI) base_uri = NULL; /* make the requirements more strict */ if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) { require_correct_aspect_ratio = TRUE; } /* relax the requirements a bit */ if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) { ss_size_height_max = 1800; ss_size_height_min = 150; ss_size_width_max = 3200; ss_size_width_min = 300; } /* have we got network access */ if ((helper->flags & AS_APP_VALIDATE_FLAG_NO_NETWORK) > 0) return TRUE; /* GET file */ url = as_image_get_url (im); g_debug ("checking %s", url); base_uri = soup_uri_new (url); if (!SOUP_URI_VALID_FOR_HTTP (base_uri)) { ai_app_validate_add (helper, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> url not valid [%s]", url); return FALSE; } msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); if (msg == NULL) { g_warning ("Failed to setup message"); return FALSE; } /* send sync */ status_code = soup_session_send_message (helper->session, msg); if (SOUP_STATUS_IS_TRANSPORT_ERROR(status_code)) { ai_app_validate_add (helper, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> failed to connect: %s [%s]", soup_status_get_phrase(status_code), url); return FALSE; } else if (status_code != SOUP_STATUS_OK) { ai_app_validate_add (helper, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> failed to download (HTTP %d: %s) [%s]", status_code, soup_status_get_phrase(status_code), url); return FALSE; } /* check if it's a zero sized file */ if (msg->response_body->length == 0) { ai_app_validate_add (helper, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> url is a zero length file [%s]", url); return FALSE; } /* create a buffer with the data */ stream = g_memory_input_stream_new_from_data (msg->response_body->data, (gssize) msg->response_body->length, NULL); if (stream == NULL) { ai_app_validate_add (helper, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> failed to load data [%s]", url); return FALSE; } /* load the image */ pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL); if (pixbuf == NULL) { ai_app_validate_add (helper, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> failed to load [%s]", url); return FALSE; } /* check width matches */ screenshot_width = (guint) gdk_pixbuf_get_width (pixbuf); screenshot_height = (guint) gdk_pixbuf_get_height (pixbuf); if (as_image_get_width (im) != 0 && as_image_get_width (im) != screenshot_width) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width did not match specified [%s]", url); } /* check height matches */ if (as_image_get_height (im) != 0 && as_image_get_height (im) != screenshot_height) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height did not match specified [%s]", url); } /* check size is reasonable */ if (screenshot_width < ss_size_width_min) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width too small [%s] minimum is %upx", url, ss_size_width_min); } if (screenshot_height < ss_size_height_min) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height too small [%s] minimum is %upx", url, ss_size_height_min); } if (screenshot_width > ss_size_width_max) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width too large [%s] maximum is %upx", url, ss_size_width_max); } if (screenshot_height > ss_size_height_max) { ai_app_validate_add (helper, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height too large [%s] maximum is %upx", url, ss_size_height_max); } /* check padding */ as_image_set_pixbuf (im, pixbuf); alpha_flags = as_image_get_alpha_flags (im); if ((alpha_flags & AS_IMAGE_ALPHA_FLAG_TOP) > 0|| (alpha_flags & AS_IMAGE_ALPHA_FLAG_BOTTOM) > 0) { ai_app_validate_add (helper, AS_PROBLEM_KIND_STYLE_INCORRECT, "<image> has vertical padding [%s]", url); } if ((alpha_flags & AS_IMAGE_ALPHA_FLAG_LEFT) > 0|| (alpha_flags & AS_IMAGE_ALPHA_FLAG_RIGHT) > 0) { ai_app_validate_add (helper, AS_PROBLEM_KIND_STYLE_INCORRECT, "<image> has horizontal padding [%s]", url); } /* check aspect ratio */ if (require_correct_aspect_ratio) { screenshot_aspect = (gdouble) screenshot_width / (gdouble) screenshot_height; if (ABS (screenshot_aspect - 1.777777777) > 0.1) { g_debug ("got aspect %.2f, wanted %.2f", screenshot_aspect, desired_aspect); ai_app_validate_add (helper, AS_PROBLEM_KIND_ASPECT_RATIO_INCORRECT, "<screenshot> aspect ratio not 16:9 [%s]", url); } } return TRUE; }
/** * ai_app_validate_image_check: */ static gboolean ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) { const gchar *url; gboolean require_correct_aspect_ratio = FALSE; gdouble desired_aspect = 1.777777778; gdouble screenshot_aspect; gint status_code; guint screenshot_height; guint screenshot_width; guint ss_size_height_max = 900; guint ss_size_height_min = 351; guint ss_size_width_max = 1600; guint ss_size_width_min = 624; _cleanup_object_unref_ GdkPixbuf *pixbuf = NULL; _cleanup_object_unref_ GInputStream *stream = NULL; _cleanup_object_unref_ SoupMessage *msg = NULL; _cleanup_uri_unref_ SoupURI *base_uri = NULL; /* make the requirements more strict */ if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) { require_correct_aspect_ratio = TRUE; } /* relax the requirements a bit */ if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) { ss_size_height_max = 1800; ss_size_height_min = 150; ss_size_width_max = 3200; ss_size_width_min = 300; } /* have we got network access */ if ((helper->flags & AS_APP_VALIDATE_FLAG_NO_NETWORK) > 0) return TRUE; /* GET file */ url = as_image_get_url (im); g_debug ("checking %s", url); base_uri = soup_uri_new (url); if (base_uri == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> url not valid"); return FALSE; } msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); if (msg == NULL) { g_warning ("Failed to setup message"); return FALSE; } /* send sync */ status_code = soup_session_send_message (helper->session, msg); if (status_code != SOUP_STATUS_OK) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> url not found"); return FALSE; } /* check if it's a zero sized file */ if (msg->response_body->length == 0) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> url is a zero length file"); return FALSE; } /* create a buffer with the data */ stream = g_memory_input_stream_new_from_data (msg->response_body->data, msg->response_body->length, NULL); if (stream == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> failed to load data"); return FALSE; } /* load the image */ pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL); if (pixbuf == NULL) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> failed to load image"); return FALSE; } /* check width matches */ screenshot_width = gdk_pixbuf_get_width (pixbuf); screenshot_height = gdk_pixbuf_get_height (pixbuf); if (as_image_get_width (im) != 0 && as_image_get_width (im) != screenshot_width) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width did not match specified"); } /* check height matches */ if (as_image_get_height (im) != 0 && as_image_get_height (im) != screenshot_height) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height did not match specified"); } /* check size is reasonable */ if (screenshot_width < ss_size_width_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width was too small"); } if (screenshot_height < ss_size_height_min) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height was too small"); } if (screenshot_width > ss_size_width_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> width was too large"); } if (screenshot_height > ss_size_height_max) { ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<screenshot> height was too large"); } /* check aspect ratio */ if (require_correct_aspect_ratio) { screenshot_aspect = (gdouble) screenshot_width / (gdouble) screenshot_height; if (ABS (screenshot_aspect - 1.777777777) > 0.1) { g_debug ("got aspect %.2f, wanted %.2f", screenshot_aspect, desired_aspect); ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_ASPECT_RATIO_INCORRECT, "<screenshot> aspect ratio was not 16:9"); } } return TRUE; }