static gboolean update_image_size_cb (gpointer user_data) { GthFileToolResize *self = user_data; self->priv->update_size_id = 0; if (self->priv->resize_task != NULL) { gth_task_cancel (self->priv->resize_task); return FALSE; } self->priv->resize_task = gth_image_task_new (_("Resizing images"), NULL, resize_task_exec, NULL, self, NULL); if (self->priv->apply_to_original) gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->resize_task), gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self))); else gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->resize_task), self->priv->preview); g_signal_connect (self->priv->resize_task, "completed", G_CALLBACK (resize_task_completed_cb), self); gth_browser_exec_task (GTH_BROWSER (gth_file_tool_get_window (GTH_FILE_TOOL (self))), self->priv->resize_task, GTH_TASK_FLAGS_DEFAULT); return FALSE; }
static gboolean apply_cb (gpointer user_data) { GthFileToolAdjustContrast *self = user_data; GtkWidget *window; if (self->priv->apply_event != 0) { g_source_remove (self->priv->apply_event); self->priv->apply_event = 0; } if (self->priv->image_task != NULL) { gth_task_cancel (self->priv->image_task); return FALSE; } window = gth_file_tool_get_window (GTH_FILE_TOOL (self)); self->priv->image_task = get_image_task_for_method (self->priv->method); if (self->priv->apply_to_original) gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->image_task), gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self))); else gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->image_task), self->priv->preview); g_signal_connect (self->priv->image_task, "completed", G_CALLBACK (image_task_completed_cb), self); gth_browser_exec_task (GTH_BROWSER (window), self->priv->image_task, GTH_TASK_FLAGS_DEFAULT); return FALSE; }
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 image_task_completed_cb (GthTask *task, GError *error, gpointer user_data) { GthFileTool *base = user_data; GthImage *destination_image; cairo_surface_t *destination; GtkWidget *window; GtkWidget *viewer_page; if (error != NULL) { g_object_unref (task); return; } destination_image = gth_image_task_get_destination (GTH_IMAGE_TASK (task)); if (destination_image == NULL) { g_object_unref (task); return; } destination = gth_image_get_cairo_surface (destination_image); window = gth_file_tool_get_window (base); viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window)); gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), destination, TRUE); cairo_surface_destroy (destination); g_object_unref (task); }
static gpointer rotate_right_exec (GthAsyncTask *task, gpointer 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_transform (source, GTH_TRANSFORM_ROTATE_90); gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }
static gboolean apply_cb (gpointer user_data) { GthFileToolGrayscale *self = user_data; GtkWidget *window; GrayscaleData *grayscale_data; if (self->priv->apply_event != 0) { g_source_remove (self->priv->apply_event); self->priv->apply_event = 0; } if (self->priv->image_task != NULL) { gth_task_cancel (self->priv->image_task); return FALSE; } window = gth_file_tool_get_window (GTH_FILE_TOOL (self)); grayscale_data = g_new0 (GrayscaleData, 1); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("brightness_radiobutton")))) grayscale_data->method = METHOD_BRIGHTNESS; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("saturation_radiobutton")))) grayscale_data->method = METHOD_SATURATION; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("average_radiobutton")))) grayscale_data->method = METHOD_AVARAGE; self->priv->image_task = gth_image_task_new (_("Applying changes"), NULL, grayscale_exec, NULL, grayscale_data, grayscale_data_free); if (self->priv->apply_to_original) gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->image_task), gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self))); else gth_image_task_set_source_surface (GTH_IMAGE_TASK (self->priv->image_task), self->priv->preview); g_signal_connect (self->priv->image_task, "completed", G_CALLBACK (image_task_completed_cb), self); gth_browser_exec_task (GTH_BROWSER (window), self->priv->image_task, FALSE); return FALSE; }
static void resize_task_completed_cb (GthTask *task, GError *error, gpointer user_data) { GthFileToolResize *self = user_data; GtkWidget *window; GtkWidget *viewer_page; self->priv->resize_task = NULL; if (self->priv->closing) { g_object_unref (task); gth_image_viewer_page_tool_reset_image (GTH_IMAGE_VIEWER_PAGE_TOOL (self)); return; } if (error != NULL) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) update_image_size (self); g_object_unref (task); return; } _cairo_clear_surface (&self->priv->new_image); self->priv->new_image = gth_image_task_get_destination_surface (GTH_IMAGE_TASK (task)); if (self->priv->new_image == NULL) { g_object_unref (task); return; } window = gth_file_tool_get_window (GTH_FILE_TOOL (self)); viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window)); gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->new_image, FALSE); if (self->priv->apply_to_original) { gth_image_history_add_surface (gth_image_viewer_page_get_history (GTH_IMAGE_VIEWER_PAGE (viewer_page)), self->priv->new_image, -1, TRUE); gth_viewer_page_focus (GTH_VIEWER_PAGE (viewer_page)); gth_file_tool_hide_options (GTH_FILE_TOOL (self)); } else { update_dimensione_info_label (self, "new_dimensions_label", self->priv->new_width, self->priv->new_height, TRUE); update_dimensione_info_label (self, "scale_factor_label", (double) self->priv->new_width / self->priv->original_width, (double) self->priv->new_height / self->priv->original_height, FALSE); } g_object_unref (task); }
static void ok_clicked_cb (GtkWidget *widget, DialogData *data) { ResizeData *resize_data; GtkTreeIter iter; char *mime_type; GthTask *resize_task; GthTask *list_task; resize_data = g_new0 (ResizeData, 1); resize_data->width = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("width_spinbutton"))); resize_data->height = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("height_spinbutton"))); resize_data->unit = units[gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")))]; resize_data->keep_aspect_ratio = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_ratio_checkbutton"))); resize_data->allow_swap = FALSE; gtk_combo_box_get_active_iter (GTK_COMBO_BOX (GET_WIDGET ("mime_type_combobox")), &iter); gtk_tree_model_get (GTK_TREE_MODEL (GET_WIDGET ("mime_type_liststore")), &iter, MIME_TYPE_COLUMN_TYPE, &mime_type, -1); g_settings_set_int (data->settings, PREF_RESIZE_IMAGES_SERIES_WIDTH, resize_data->width); g_settings_set_int (data->settings, PREF_RESIZE_IMAGES_SERIES_HEIGHT, resize_data->height); g_settings_set_enum (data->settings, PREF_RESIZE_IMAGES_UNIT, resize_data->unit); g_settings_set_boolean (data->settings, PREF_RESIZE_IMAGES_KEEP_RATIO, resize_data->keep_aspect_ratio); g_settings_set_string (data->settings, PREF_RESIZE_IMAGES_MIME_TYPE, mime_type ? mime_type : ""); resize_task = gth_image_task_new (_("Resizing images"), NULL, exec_resize, NULL, resize_data, g_free); list_task = gth_image_list_task_new (data->browser, data->file_list, GTH_IMAGE_TASK (resize_task)); gth_image_list_task_set_overwrite_mode (GTH_IMAGE_LIST_TASK (list_task), GTH_OVERWRITE_ASK); gth_image_list_task_set_output_mime_type (GTH_IMAGE_LIST_TASK (list_task), mime_type); if (data->use_destination) { GFile *destination; destination = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton"))); gth_image_list_task_set_destination (GTH_IMAGE_LIST_TASK (list_task), destination); g_object_unref (destination); } gth_browser_exec_task (data->browser, list_task, FALSE); g_object_unref (list_task); g_object_unref (resize_task); g_free (mime_type); gtk_widget_destroy (data->dialog); }
static void image_task_completed_cb (GthTask *task, GError *error, gpointer user_data) { GthFileToolAdjustContrast *self = user_data; GthImage *destination_image; self->priv->image_task = NULL; if (self->priv->closing) { g_object_unref (task); gth_image_viewer_page_tool_reset_image (GTH_IMAGE_VIEWER_PAGE_TOOL (self)); return; } if (error != NULL) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) apply_changes (self); g_object_unref (task); return; } destination_image = gth_image_task_get_destination (GTH_IMAGE_TASK (task)); if (destination_image == NULL) { g_object_unref (task); return; } cairo_surface_destroy (self->priv->destination); self->priv->destination = gth_image_get_cairo_surface (destination_image); self->priv->last_applied_method = self->priv->method; if (self->priv->apply_to_original) { if (self->priv->destination != NULL) { GtkWidget *window; GtkWidget *viewer_page; window = gth_file_tool_get_window (GTH_FILE_TOOL (self)); viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window)); gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->destination, TRUE); } gth_file_tool_hide_options (GTH_FILE_TOOL (self)); } else { if (! self->priv->view_original) gth_preview_tool_set_image (GTH_PREVIEW_TOOL (self->priv->preview_tool), self->priv->destination); } g_object_unref (task); }
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; }
static gpointer adjust_contrast_exec (GthAsyncTask *task, gpointer user_data) { AdjustContrastData *adjust_data = user_data; cairo_format_t format; int width; int height; int source_stride; cairo_surface_t *destination; int destination_stride; unsigned char *p_source_line; unsigned char *p_destination_line; unsigned char *p_source; unsigned char *p_destination; gboolean cancelled; double progress; int x, y; unsigned char red, green, blue, alpha; GthImage *destination_image; /* initialize some extra data */ adjust_contrast_setup (adjust_data); /* convert the image */ format = cairo_image_surface_get_format (adjust_data->source); width = cairo_image_surface_get_width (adjust_data->source); height = cairo_image_surface_get_height (adjust_data->source); source_stride = cairo_image_surface_get_stride (adjust_data->source); destination = cairo_image_surface_create (format, width, height); destination_stride = cairo_image_surface_get_stride (destination); p_source_line = _cairo_image_surface_flush_and_get_data (adjust_data->source); p_destination_line = _cairo_image_surface_flush_and_get_data (destination); for (y = 0; y < height; y++) { gth_async_task_get_data (task, NULL, &cancelled, NULL); if (cancelled) return NULL; progress = (double) y / height; gth_async_task_set_data (task, NULL, NULL, &progress); p_source = p_source_line; p_destination = p_destination_line; for (x = 0; x < width; x++) { CAIRO_GET_RGBA (p_source, red, green, blue, alpha); red = adjust_contrast_func (adjust_data, GTH_HISTOGRAM_CHANNEL_RED, red); green = adjust_contrast_func (adjust_data, GTH_HISTOGRAM_CHANNEL_GREEN, green); blue = adjust_contrast_func (adjust_data, GTH_HISTOGRAM_CHANNEL_BLUE, blue); CAIRO_SET_RGBA (p_destination, red, green, blue, alpha); p_source += 4; p_destination += 4; } p_source_line += source_stride; p_destination_line += destination_stride; } cairo_surface_mark_dirty (destination); 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); return NULL; }
static gpointer grayscale_exec (GthAsyncTask *task, gpointer user_data) { GrayscaleData *grayscale_data = user_data; cairo_surface_t *source; cairo_format_t format; int width; int height; int source_stride; cairo_surface_t *destination; int destination_stride; unsigned char *p_source_line; unsigned char *p_destination_line; unsigned char *p_source; unsigned char *p_destination; gboolean cancelled; double progress; int x, y; unsigned char red, green, blue, alpha; unsigned char min, max, value; source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task)); format = cairo_image_surface_get_format (source); width = cairo_image_surface_get_width (source); height = cairo_image_surface_get_height (source); source_stride = cairo_image_surface_get_stride (source); destination = cairo_image_surface_create (format, width, height); destination_stride = cairo_image_surface_get_stride (destination); p_source_line = _cairo_image_surface_flush_and_get_data (source); p_destination_line = _cairo_image_surface_flush_and_get_data (destination); for (y = 0; y < height; y++) { gth_async_task_get_data (task, NULL, &cancelled, NULL); if (cancelled) return NULL; progress = (double) y / height; gth_async_task_set_data (task, NULL, NULL, &progress); p_source = p_source_line; p_destination = p_destination_line; for (x = 0; x < width; x++) { CAIRO_GET_RGBA (p_source, red, green, blue, alpha); switch (grayscale_data->method) { case METHOD_BRIGHTNESS: value = (0.2125 * red + 0.7154 * green + 0.072 * blue); break; case METHOD_SATURATION: max = MAX (MAX (red, green), blue); min = MIN (MIN (red, green), blue); value = (max + min) / 2; break; case METHOD_AVARAGE: value = (0.3333 * red + 0.3333 * green + 0.3333 * blue); break; default: g_assert_not_reached (); } CAIRO_SET_RGBA (p_destination, value, value, value, alpha); p_source += 4; p_destination += 4; } p_source_line += source_stride; p_destination_line += destination_stride; } cairo_surface_mark_dirty (destination); gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }
static gpointer negative_exec (GthAsyncTask *task, gpointer user_data) { cairo_surface_t *source; cairo_format_t format; int width; int height; int source_stride; cairo_surface_t *destination; int destination_stride; unsigned char *p_source_line; unsigned char *p_destination_line; unsigned char *p_source; unsigned char *p_destination; gboolean cancelled; double progress; int x, y; unsigned char red, green, blue, alpha; source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task)); format = cairo_image_surface_get_format (source); width = cairo_image_surface_get_width (source); height = cairo_image_surface_get_height (source); source_stride = cairo_image_surface_get_stride (source); destination = cairo_image_surface_create (format, width, height); destination_stride = cairo_image_surface_get_stride (destination); p_source_line = _cairo_image_surface_flush_and_get_data (source); p_destination_line = _cairo_image_surface_flush_and_get_data (destination); for (y = 0; y < height; y++) { gth_async_task_get_data (task, NULL, &cancelled, NULL); if (cancelled) return NULL; progress = (double) y / height; gth_async_task_set_data (task, NULL, NULL, &progress); p_source = p_source_line; p_destination = p_destination_line; for (x = 0; x < width; x++) { CAIRO_GET_RGBA (p_source, red, green, blue, alpha); CAIRO_SET_RGBA (p_destination, 255 - red, 255 - green, 255 - blue, alpha); p_source += 4; p_destination += 4; } p_source_line += source_stride; p_destination_line += destination_stride; } cairo_surface_mark_dirty (destination); gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination); cairo_surface_destroy (destination); cairo_surface_destroy (source); return NULL; }