From 91df48ef3708227ba2f2474b054baf62e2c7699a Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 9 Nov 2016 13:10:56 +0100 Subject: [PATCH] Bug 735895 - Precision Conversion "Dithering" dialog Disable the convert precision dialog's dithering controls when converting to higher bit depths o to anything > 16 bit. Make sure the disabled dithering widgets always says "None", which implies duplicating the bit depth checking logic in both the dialog and its callback, in order to protect the values in GimpDialogConfig from being overwritten by NONE. --- app/actions/image-commands.c | 31 +++++++++++ app/dialogs/convert-precision-dialog.c | 72 ++++++++++++++++---------- 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c index 890c641a06..9f49cfa50b 100644 --- a/app/actions/image-commands.c +++ b/app/actions/image-commands.c @@ -1165,6 +1165,10 @@ image_convert_precision_callback (GtkWidget *dialog, GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config); GimpProgress *progress = user_data; const gchar *enum_desc; + const Babl *old_format; + const Babl *new_format; + gint old_bits; + gint new_bits; g_object_set (config, "image-convert-precision-layer-dither-method", @@ -1175,6 +1179,33 @@ image_convert_precision_callback (GtkWidget *dialog, channel_dither_method, NULL); + /* we do the same dither method checks here *and* in the dialog, + * because the dialog leaves the passed dither methods untouched if + * dithering is disabled and passes the original values to the + * callback, in order not to change the values saved in + * GimpDialogConfig. + */ + + /* random formats with the right precision */ + old_format = gimp_image_get_layer_format (image, FALSE); + new_format = gimp_babl_format (GIMP_RGB, precision, FALSE); + + old_bits = (babl_format_get_bytes_per_pixel (old_format) * 8 / + babl_format_get_n_components (old_format)); + new_bits = (babl_format_get_bytes_per_pixel (new_format) * 8 / + babl_format_get_n_components (new_format)); + + if (new_bits >= old_bits || new_bits > 16) + { + /* don't dither if we are converting to a higher bit depth, + * or to more than 16 bits (gegl:color-reduction only does + * 16 bits). + */ + layer_dither_method = GEGL_DITHER_NONE; + text_layer_dither_method = GEGL_DITHER_NONE; + channel_dither_method = GEGL_DITHER_NONE; + } + gimp_enum_get_value (GIMP_TYPE_PRECISION, precision, NULL, NULL, &enum_desc, NULL); diff --git a/app/dialogs/convert-precision-dialog.c b/app/dialogs/convert-precision-dialog.c index 0ecbc1dea6..ed50fe22fc 100644 --- a/app/dialogs/convert-precision-dialog.c +++ b/app/dialogs/convert-precision-dialog.c @@ -46,7 +46,6 @@ struct _ConvertDialog GimpImage *image; GimpComponentType component_type; gboolean linear; - gint bits; GeglDitherMethod layer_dither_method; GeglDitherMethod text_layer_dither_method; GeglDitherMethod channel_dither_method; @@ -89,8 +88,11 @@ convert_precision_dialog_new (GimpImage *image, GtkSizeGroup *size_group; const gchar *enum_desc; gchar *blurb; - const Babl *format; - gint bits; + const Babl *old_format; + const Babl *new_format; + gint old_bits; + gint new_bits; + gboolean dither; gboolean linear; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); @@ -98,22 +100,29 @@ convert_precision_dialog_new (GimpImage *image, g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL); g_return_val_if_fail (callback != NULL, NULL); - /* a random format with precision */ - format = gimp_babl_format (GIMP_RGB, - gimp_babl_precision (component_type, FALSE), - FALSE); - bits = (babl_format_get_bytes_per_pixel (format) * 8 / - babl_format_get_n_components (format)); + /* random formats with the right precision */ + old_format = gimp_image_get_layer_format (image, FALSE); + new_format = gimp_babl_format (GIMP_RGB, + gimp_babl_precision (component_type, FALSE), + FALSE); - linear = gimp_babl_format_get_linear (gimp_image_get_layer_format (image, - FALSE)); + old_bits = (babl_format_get_bytes_per_pixel (old_format) * 8 / + babl_format_get_n_components (old_format)); + new_bits = (babl_format_get_bytes_per_pixel (new_format) * 8 / + babl_format_get_n_components (new_format)); + + /* don't dither if we are converting to a higher bit depth, or to + * more than 16 bits (gegl:color-reduction only does 16 bits). + */ + dither = (new_bits < old_bits && new_bits <= 16); + + linear = gimp_babl_format_get_linear (old_format); private = g_slice_new0 (ConvertDialog); private->image = image; private->component_type = component_type; private->linear = linear; - private->bits = bits; private->layer_dither_method = layer_dither_method; private->text_layer_dither_method = text_layer_dither_method; private->channel_dither_method = channel_dither_method; @@ -177,8 +186,7 @@ convert_precision_dialog_new (GimpImage *image, gtk_container_add (GTK_CONTAINER (frame), vbox); gtk_widget_show (vbox); - /* gegl:color-reduction only does 16 bits */ - gtk_widget_set_sensitive (vbox, bits <= 16); + gtk_widget_set_sensitive (vbox, dither); size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); @@ -199,10 +207,14 @@ convert_precision_dialog_new (GimpImage *image, gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0); gtk_widget_show (combo); - gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), - private->layer_dither_method, - G_CALLBACK (gimp_int_combo_box_get_active), - &private->layer_dither_method); + if (dither) + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), + private->layer_dither_method, + G_CALLBACK (gimp_int_combo_box_get_active), + &private->layer_dither_method); + else + gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), + GEGL_DITHER_NONE); /* text layers */ @@ -221,10 +233,14 @@ convert_precision_dialog_new (GimpImage *image, gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0); gtk_widget_show (combo); - gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), - private->text_layer_dither_method, - G_CALLBACK (gimp_int_combo_box_get_active), - &private->text_layer_dither_method); + if (dither) + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), + private->text_layer_dither_method, + G_CALLBACK (gimp_int_combo_box_get_active), + &private->text_layer_dither_method); + else + gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), + GEGL_DITHER_NONE); gimp_help_set_help_data (combo, _("Dithering text layers will make them uneditable"), @@ -247,10 +263,14 @@ convert_precision_dialog_new (GimpImage *image, gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0); gtk_widget_show (combo); - gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), - private->channel_dither_method, - G_CALLBACK (gimp_int_combo_box_get_active), - &private->channel_dither_method); + if (dither) + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), + private->channel_dither_method, + G_CALLBACK (gimp_int_combo_box_get_active), + &private->channel_dither_method); + else + gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), + GEGL_DITHER_NONE); g_object_unref (size_group);