void gth_image_info_set_image (GthImageInfo *image_info, cairo_surface_t *image) { int thumb_w; int thumb_h; g_return_if_fail (image != NULL); _cairo_clear_surface (&image_info->image); _cairo_clear_surface (&image_info->thumbnail_original); _cairo_clear_surface (&image_info->thumbnail); _cairo_clear_surface (&image_info->thumbnail_active); image_info->image = cairo_surface_reference (image); thumb_w = image_info->original_width = image_info->image_width = cairo_image_surface_get_width (image); thumb_h = image_info->original_height = image_info->image_height = cairo_image_surface_get_height (image); if (scale_keeping_ratio (&thumb_w, &thumb_h, THUMBNAIL_SIZE, THUMBNAIL_SIZE, FALSE)) image_info->thumbnail_original = _cairo_image_surface_scale (image, thumb_w, thumb_h, SCALE_FILTER_BEST, NULL); else image_info->thumbnail_original = cairo_surface_reference (image_info->image); image_info->thumbnail = cairo_surface_reference (image_info->thumbnail_original); image_info->thumbnail_active = _cairo_image_surface_color_shift (image_info->thumbnail, 30); }
static gpointer exec_resize (GthAsyncTask *task, gpointer user_data) { ResizeData *resize_data = user_data; cairo_surface_t *source; cairo_surface_t *destination; int w, h; int new_w, new_h; int max_w, max_h; GthImage *destination_image; source = gth_image_get_cairo_surface (gth_image_task_get_source (GTH_IMAGE_TASK (task))); w = cairo_image_surface_get_width (source); h = cairo_image_surface_get_height (source); if (resize_data->allow_swap && (((h > w) && (resize_data->width > resize_data->height)) || ((h < w) && (resize_data->width < resize_data->height)))) { max_w = resize_data->height; max_h = resize_data->width; } else { max_w = resize_data->width; max_h = resize_data->height; } if (resize_data->unit == GTH_UNIT_PERCENTAGE) { new_w = w * ((double) max_w / 100.0); new_h = h * ((double) max_h / 100.0); } else if (resize_data->keep_aspect_ratio) { new_w = w; new_h = h; scale_keeping_ratio (&new_w, &new_h, max_w, max_h, TRUE); } else { new_w = max_w; new_h = max_h; } if ((new_w > 1) && (new_h > 1)) destination = _cairo_image_surface_scale (source, new_w, new_h, SCALE_FILTER_BEST, task); else destination = NULL; destination_image = gth_image_new_for_surface (destination); gth_image_task_set_destination (GTH_IMAGE_TASK (task), destination_image); _g_object_unref (destination_image); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }
static void scale_image_thread (GSimpleAsyncResult *result, GObject *object, GCancellable *cancellable) { ScaleData *scale_data; scale_data = g_simple_async_result_get_op_res_gpointer (result); scale_data->scaled = _cairo_image_surface_scale (scale_data->original, scale_data->new_width, scale_data->new_height, scale_data->quality, GTH_ASYNC_TASK (scale_data->task)); }
cairo_surface_t * _cairo_image_surface_scale_squared (cairo_surface_t *image, int size, scale_filter_t quality, GthAsyncTask *task) { int width, height; int scaled_width, scaled_height; cairo_surface_t *scaled; cairo_surface_t *squared; width = cairo_image_surface_get_width (image); height = cairo_image_surface_get_height (image); if ((width < size) && (height < size)) return _cairo_image_surface_copy (image); if (width > height) { scaled_height = size; scaled_width = (int) (((double) width / height) * scaled_height); } else { scaled_width = size; scaled_height = (int) (((double) height / width) * scaled_width); } if ((scaled_width != width) || (scaled_height != height)) scaled = _cairo_image_surface_scale (image, scaled_width, scaled_height, quality, task); else scaled = cairo_surface_reference (image); if ((scaled_width == size) && (scaled_height == size)) return scaled; squared = _cairo_image_surface_copy_subsurface (scaled, (scaled_width - size) / 2, (scaled_height - size) / 2, size, size); cairo_surface_destroy (scaled); return squared; }
static gpointer resize_task_exec (GthAsyncTask *task, gpointer user_data) { GthFileToolResize *self = user_data; cairo_surface_t *source; cairo_surface_t *destination; source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task)); destination = _cairo_image_surface_scale (source, self->priv->new_width, self->priv->new_height, (self->priv->high_quality ? SCALE_FILTER_BEST : SCALE_FILTER_FAST), task); _cairo_image_surface_clear_metadata (destination); gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }
gboolean _g_buffer_resize_image (void *buffer, gsize count, GthFileData *file_data, int max_width, int max_height, void **resized_buffer, gsize *resized_count, GCancellable *cancellable, GError **error) { GInputStream *istream; const char *mime_type; GthImageLoaderFunc loader_func; GthImage *image; int width; int height; cairo_surface_t *surface; cairo_surface_t *scaled; gboolean result; if ((max_width == -1) || (max_height == -1)) { *error = NULL; return FALSE; } istream = g_memory_input_stream_new_from_data (buffer, count, NULL); mime_type = _g_content_type_get_from_stream (istream, (file_data != NULL ? file_data->file : NULL), cancellable, NULL); if (mime_type == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "%s", _("No suitable loader available for this file type")); return FALSE; } loader_func = gth_main_get_image_loader_func (mime_type, GTH_IMAGE_FORMAT_CAIRO_SURFACE); if (loader_func == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "%s", _("No suitable loader available for this file type")); g_object_unref (istream); return FALSE; } image = loader_func (istream, NULL, -1, &width, &height, NULL, cancellable, error); if (image == NULL) { g_object_unref (istream); return FALSE; } if (! scale_keeping_ratio (&width, &height, max_width, max_height, FALSE)) { error = NULL; g_object_unref (image); g_object_unref (istream); return FALSE; } surface = gth_image_get_cairo_surface (image); scaled = _cairo_image_surface_scale (surface, width, height, SCALE_FILTER_BEST, NULL); gth_image_set_cairo_surface (image, scaled); result = gth_image_save_to_buffer (image, mime_type, file_data, (char **) resized_buffer, resized_count, cancellable, error); cairo_surface_destroy (scaled); cairo_surface_destroy (surface); g_object_unref (image); g_object_unref (istream); return result; }