[gimp] plug-ins: port file-jpeg export procedure to new API.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port file-jpeg export procedure to new API.
- Date: Wed, 25 Nov 2020 22:12:01 +0000 (UTC)
commit 731537befd6b13c8679b8555f8f56286d58e0a9b
Author: Jehan <jehan girinstud io>
Date: Wed Nov 25 22:44:43 2020 +0100
plug-ins: port file-jpeg export procedure to new API.
This is nearly 600 lines less for basically the same logics! Removed
code is in particular all the GUI code is favor of the new GUI
generation.
I also cleaned a lot of stuff, removing many global variables or ugly
pieces of code. I also removed a lot of redundant code of things which
are now generic, such as handling of "gimp-comment" parasite (this is
now handled by GimpSaveProcedure and GimpImageMetadata) as well as
saving previous run's values (this is also handled generically).
Note that Advanced Options used to be in an expander. For now I chose to
get them immediately visible (still in their own "Advanced Options"
section, but it's now a normal frame, not an expander hidden by default)
since lately we got some input that many "advanced options" in various
dialogs should not be hidden away. So let's try like this for now (even
though it packs quite a lot of options in the same dialog!).
I thoroughly tested, yet that were so many changes that bugs may have
sneaked in. Please anyone, test JPEG export!
plug-ins/file-jpeg/jpeg-save.c | 1028 +++++++++---------------------------
plug-ins/file-jpeg/jpeg-save.h | 40 +-
plug-ins/file-jpeg/jpeg-settings.c | 4 +-
plug-ins/file-jpeg/jpeg.c | 289 ++++------
plug-ins/file-jpeg/jpeg.h | 4 -
5 files changed, 384 insertions(+), 981 deletions(-)
---
diff --git a/plug-ins/file-jpeg/jpeg-save.c b/plug-ins/file-jpeg/jpeg-save.c
index 8f2537b05f..83a8e13162 100644
--- a/plug-ins/file-jpeg/jpeg-save.c
+++ b/plug-ins/file-jpeg/jpeg-save.c
@@ -44,32 +44,8 @@
#include "jpeg-save.h"
#include "jpeg-settings.h"
-#ifdef C_ARITH_CODING_SUPPORTED
-static gboolean arithc_supported = TRUE;
-#else
-static gboolean arithc_supported = FALSE;
-#endif
-
/* See bugs #63610 and #61088 for a discussion about the quality settings */
-#define DEFAULT_IJG_QUALITY 90.0
-#define DEFAULT_SMOOTHING 0.0
-#define DEFAULT_OPTIMIZE TRUE
-#define DEFAULT_ARITHMETIC_CODING FALSE
-#define DEFAULT_PROGRESSIVE TRUE
-#define DEFAULT_BASELINE TRUE
-#define DEFAULT_SUBSMP JPEG_SUBSAMPLING_1x1_1x1_1x1
-#define DEFAULT_RESTART 0
#define DEFAULT_RESTART_MCU_ROWS 16
-#define DEFAULT_DCT 0
-#define DEFAULT_PREVIEW FALSE
-#define DEFAULT_EXIF FALSE
-#define DEFAULT_XMP FALSE
-#define DEFAULT_IPTC FALSE
-#define DEFAULT_THUMBNAIL FALSE
-#define DEFAULT_PROFILE TRUE
-#define DEFAULT_USE_ORIG_QUALITY FALSE
-
-#define JPEG_DEFAULTS_PARASITE "jpeg-save-defaults"
typedef struct
@@ -89,61 +65,19 @@ typedef struct
guint source_id;
} PreviewPersistent;
-/*le added : struct containing pointers to export dialog*/
-typedef struct
-{
- gboolean run;
- GtkWidget *use_restart_markers; /*checkbox setting use restart markers*/
- GtkTextBuffer *text_buffer;
- GtkAdjustment *scale_data; /*for restart markers*/
- gulong handler_id_restart;
-
- GtkWidget *quality; /*quality slidebar*/
- GtkWidget *smoothing; /*smoothing slidebar*/
- GtkWidget *optimize; /*optimize toggle*/
- GtkWidget *arithmetic_coding; /*arithmetic coding toggle*/
- GtkWidget *progressive; /*progressive toggle*/
- GtkWidget *subsmp; /*subsampling side select*/
- GtkWidget *restart; /*spinner for setting frequency restart markers*/
- GtkWidget *dct; /*DCT side select*/
- GtkWidget *preview; /*show preview toggle checkbox*/
- GtkWidget *save_exif;
- GtkWidget *save_xmp;
- GtkWidget *save_iptc;
- GtkWidget *save_thumbnail;
- GtkWidget *save_profile;
- GtkWidget *use_orig_quality; /*quant tables toggle*/
-} JpegSaveGui;
-
-static void make_preview (void);
-
-static void scale_entry_update (GimpLabelSpin *entry,
- gdouble *value);
-static void save_restart_update (GtkAdjustment *adjustment,
- GtkWidget *toggle);
-static void subsampling_changed (GtkWidget *combo,
- GtkWidget *entry);
-static void quality_changed (GimpScaleEntry *scale_entry,
- GtkWidget *toggle);
-static void subsampling_changed2 (GtkWidget *combo,
- GtkWidget *toggle);
-static void use_orig_qual_changed (GtkWidget *toggle,
- GimpLabelSpin *scale_entry);
-static void use_orig_qual_changed2 (GtkWidget *toggle,
- GtkWidget *combo);
-
-
-static GtkWidget *restart_markers_scale = NULL;
-static GtkWidget *restart_markers_label = NULL;
-static GtkWidget *preview_size = NULL;
-static PreviewPersistent *prev_p = NULL;
-static void save_dialog_response (GtkWidget *widget,
- gint response_id,
- gpointer data);
+static void make_preview (GimpProcedureConfig *config);
-static void load_gui_defaults (JpegSaveGui *pg);
-static void save_defaults (void);
+static void quality_changed (GimpProcedureConfig *config);
+static void subsampling_changed (GimpProcedureConfig *config,
+ const GParamSpec *pspec,
+ GtkWidget *smoothing_scale);
+static void use_orig_qual_changed (GimpProcedureConfig *config);
+static void use_orig_qual_changed_rgb (GimpProcedureConfig *config);
+
+
+static GtkWidget *preview_size = NULL;
+static PreviewPersistent *prev_p = NULL;
/*
@@ -259,12 +193,13 @@ background_jpeg_save (PreviewPersistent *pp)
}
gboolean
-save_image (GFile *file,
- GimpImage *image,
- GimpDrawable *drawable,
- GimpImage *orig_image,
- gboolean preview,
- GError **error)
+save_image (GFile *file,
+ GimpProcedureConfig *config,
+ GimpImage *image,
+ GimpDrawable *drawable,
+ GimpImage *orig_image,
+ gboolean preview,
+ GError **error)
{
static struct jpeg_compress_struct cinfo;
static struct my_error_mgr jerr;
@@ -285,6 +220,48 @@ save_image (GFile *file,
gboolean out_linear = FALSE;
gint rowstride, yend;
+ gint quality;
+ gdouble dquality = 1.0;
+ gdouble smoothing;
+ gboolean optimize;
+ gboolean progressive;
+ gint subsmp;
+ gboolean baseline;
+ gint restart;
+ gint dct;
+ gboolean save_profile = TRUE;
+ gboolean save_comment;
+ gboolean use_orig_quality = FALSE;
+ gint orig_num_quant_tables = -1;
+ gboolean use_arithmetic_coding = FALSE;
+ gboolean use_restart = FALSE;
+ gchar *comment;
+
+ g_object_get (config,
+ "quality", &dquality,
+ "smoothing", &smoothing,
+ "optimize", &optimize,
+ "progressive", &progressive,
+ "sub-sampling", &subsmp,
+ "baseline", &baseline,
+ "restart", &restart,
+ "dct", &dct,
+
+ /* Original quality settings. */
+ "use-original-quality", &use_orig_quality,
+ "original-num-quant-tables", &orig_num_quant_tables,
+
+ "use-arithmetic-coding", &use_arithmetic_coding,
+ "use-restart", &use_restart,
+
+ "save-color-profile", &save_profile,
+ "save-comment", &save_comment,
+ "gimp-comment", &comment,
+
+ NULL);
+
+ quality = (gint) (dquality * 100.0 + 0.5);
+
drawable_type = gimp_drawable_type (drawable);
buffer = gimp_drawable_get_buffer (drawable);
space = gimp_drawable_get_format (drawable);
@@ -348,7 +325,7 @@ save_image (GFile *file,
* If we save the default linear profile (i.e. no assigned
* profile), we convert it to sRGB, except when it is 8-bit linear.
*/
- if (jsvals.save_profile)
+ if (save_profile)
{
profile = gimp_image_get_color_profile (orig_image);
@@ -472,47 +449,46 @@ save_image (GFile *file,
*/
jpeg_set_defaults (&cinfo);
- jpeg_set_quality (&cinfo, (gint) (jsvals.quality + 0.5), jsvals.baseline);
+ jpeg_set_quality (&cinfo, quality, baseline);
- if (jsvals.use_orig_quality && num_quant_tables > 0)
+ if (use_orig_quality && orig_num_quant_tables > 0)
{
guint **quant_tables;
gint t;
/* override tables generated by jpeg_set_quality() with custom tables */
- quant_tables = jpeg_restore_original_tables (image, num_quant_tables);
+ quant_tables = jpeg_restore_original_tables (image, orig_num_quant_tables);
if (quant_tables)
{
- for (t = 0; t < num_quant_tables; t++)
+ for (t = 0; t < orig_num_quant_tables; t++)
{
jpeg_add_quant_table (&cinfo, t, quant_tables[t],
- 100, jsvals.baseline);
+ 100, baseline);
g_free (quant_tables[t]);
}
g_free (quant_tables);
}
}
- if (arithc_supported)
- {
- cinfo.arith_code = jsvals.arithmetic_coding;
- if (!jsvals.arithmetic_coding)
- cinfo.optimize_coding = jsvals.optimize;
- }
- else
- cinfo.optimize_coding = jsvals.optimize;
+#ifdef C_ARITH_CODING_SUPPORTED
+ cinfo.arith_code = use_arithmetic_coding;
+ if (! use_arithmetic_coding)
+ cinfo.optimize_coding = optimize;
+#else
+ cinfo.optimize_coding = optimize;
+#endif
subsampling = (gimp_drawable_is_rgb (drawable) ?
- jsvals.subsmp : JPEG_SUBSAMPLING_1x1_1x1_1x1);
+ subsmp : JPEG_SUBSAMPLING_1x1_1x1_1x1);
/* smoothing is not supported with nonstandard sampling ratios */
if (subsampling != JPEG_SUBSAMPLING_2x1_1x1_1x1 &&
subsampling != JPEG_SUBSAMPLING_1x2_1x1_1x1)
{
- cinfo.smoothing_factor = (gint) (jsvals.smoothing * 100);
+ cinfo.smoothing_factor = (gint) (smoothing * 100);
}
- if (jsvals.progressive)
+ if (progressive)
{
jpeg_simple_progression (&cinfo);
}
@@ -558,9 +534,9 @@ save_image (GFile *file,
}
cinfo.restart_interval = 0;
- cinfo.restart_in_rows = jsvals.restart;
+ cinfo.restart_in_rows = use_restart ? restart : 0;
- switch (jsvals.dct)
+ switch (dct)
{
case 0:
default:
@@ -614,18 +590,18 @@ save_image (GFile *file,
jpeg_start_compress (&cinfo, TRUE);
/* Step 4.1: Write the comment out - pw */
- if (image_comment && *image_comment)
+ if (save_comment && comment && *comment)
{
#ifdef GIMP_UNSTABLE
g_print ("jpeg-save: saving image comment (%d bytes)\n",
- (int) strlen (image_comment));
+ (int) strlen (comment));
#endif
jpeg_write_marker (&cinfo, JPEG_COM,
- (guchar *) image_comment, strlen (image_comment));
+ (guchar *) comment, strlen (comment));
}
/* Step 4.2: store the color profile */
- if (jsvals.save_profile)
+ if (save_profile)
{
const guint8 *icc_data;
gsize icc_length;
@@ -738,11 +714,15 @@ save_image (GFile *file,
}
static void
-make_preview (void)
+make_preview (GimpProcedureConfig *config)
{
+ gboolean show_preview;
+
destroy_preview ();
- if (jsvals.preview)
+ g_object_get (config, "show-preview", &show_preview, NULL);
+
+ if (show_preview)
{
GFile *file = gimp_temp_file ("jpeg");
@@ -755,7 +735,7 @@ make_preview (void)
undo_touched = TRUE;
}
- save_image (file,
+ save_image (file, config,
preview_image,
drawable_global,
orig_image_global,
@@ -798,726 +778,236 @@ destroy_preview (void)
}
}
-static void
-toggle_arithmetic_coding (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- GtkWidget *optimize = GTK_WIDGET (user_data);
-
- gtk_widget_set_sensitive (optimize,
- !gtk_toggle_button_get_active (togglebutton));
-}
-
gboolean
-save_dialog (GimpDrawable *drawable)
+save_dialog (GimpProcedure *procedure,
+ GimpProcedureConfig *config,
+ GimpDrawable *drawable)
{
- JpegSaveGui pg;
- GtkWidget *dialog;
- GtkWidget *vbox;
- GtkWidget *vbox2;
- GtkWidget *grid;
- GtkWidget *griddefaults;
- GtkWidget *expander;
- GtkWidget *frame;
- GtkWidget *toggle;
- GtkWidget *spinbutton;
- GtkWidget *label;
- GtkWidget *combo;
- GtkWidget *text_view;
- GtkTextBuffer *text_buffer;
- GtkWidget *scrolled_window;
- GtkWidget *button;
- gchar *text;
- gint row;
-
- dialog = gimp_export_dialog_new (_("JPEG"), PLUG_IN_BINARY, SAVE_PROC);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (save_dialog_response),
- &pg);
- g_signal_connect (dialog, "destroy",
- G_CALLBACK (gtk_main_quit),
- NULL);
-
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
- vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
- gtk_widget_show (vbox2);
-
- pg.quality = gimp_scale_entry_new (_("_Quality:"), jsvals.quality, 0.0, 100.0, 0);
- gimp_help_set_help_data (pg.quality, _("JPEG quality parameter"), "file-jpeg-save-quality");
-
- g_signal_connect (pg.quality, "value-changed",
- G_CALLBACK (scale_entry_update),
- &jsvals.quality);
- g_signal_connect (pg.quality, "value-changed",
- G_CALLBACK (make_preview),
- NULL);
- gtk_box_pack_start (GTK_BOX (vbox2), pg.quality, FALSE, FALSE, 0);
- gtk_widget_show (pg.quality);
+ GtkWidget *dialog;
+ GtkWidget *widget;
+ GtkListStore *store;
+ gint orig_quality;
+ gint restart;
+ gboolean run;
+
+ g_object_get (config,
+ "original-quality", &orig_quality,
+ "restart", &restart,
+ NULL);
+
+ dialog = gimp_save_procedure_dialog_new (GIMP_SAVE_PROCEDURE (procedure),
+ GIMP_PROCEDURE_CONFIG (config),
+ _("Export Image as JPEG"));
/* custom quantization tables - now used also for original quality */
- pg.use_orig_quality = toggle =
- gtk_check_button_new_with_mnemonic (_("_Use quality settings from original "
- "image"));
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- gimp_help_set_help_data (toggle,
- _("If the original image was loaded from a JPEG "
- "file using non-standard quality settings "
- "(quantization tables), enable this option to "
- "get almost the same quality and file size."),
- NULL);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.use_orig_quality);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
- jsvals.use_orig_quality
- && (orig_quality > 0)
- && (orig_subsmp == jsvals.subsmp)
- );
- gtk_widget_set_sensitive (toggle, (orig_quality > 0));
+ widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
+ "use-original-quality", G_TYPE_NONE);
+ gtk_widget_set_sensitive (widget, (orig_quality > 0));
+
+ /* Quality as a GimpScaleEntry. */
+ gimp_procedure_dialog_get_scale_entry (GIMP_PROCEDURE_DIALOG (dialog), "quality", 100.0);
/* changing quality disables custom quantization tables, and vice-versa */
- g_signal_connect (pg.quality, "value-changed",
+ g_signal_connect (config, "notify::quality",
G_CALLBACK (quality_changed),
- pg.use_orig_quality);
- g_signal_connect (pg.use_orig_quality, "toggled",
+ NULL);
+ g_signal_connect (config, "notify::use-original-quality",
G_CALLBACK (use_orig_qual_changed),
- pg.quality);
-
- /* File size */
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
- gtk_widget_show (vbox2);
+ NULL);
- preview_size = gtk_label_new (_("File size: unknown"));
+ /* File size label. */
+ preview_size = gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
+ "preview-size", _("File size: unknown"));
gtk_label_set_xalign (GTK_LABEL (preview_size), 0.0);
gtk_label_set_ellipsize (GTK_LABEL (preview_size), PANGO_ELLIPSIZE_END);
gimp_label_set_attributes (GTK_LABEL (preview_size),
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
-1);
- gtk_box_pack_start (GTK_BOX (vbox2), preview_size, FALSE, FALSE, 0);
- gtk_widget_show (preview_size);
-
gimp_help_set_help_data (preview_size,
_("Enable preview to obtain the file size."), NULL);
- pg.preview = toggle =
- gtk_check_button_new_with_mnemonic (_("Sho_w preview in image window"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.preview);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.preview);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
- gtk_widget_show (vbox2);
-
- /* Save EXIF data */
- pg.save_exif = toggle =
- gtk_check_button_new_with_mnemonic (_("Save _Exif data"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.save_exif);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.save_exif);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- /* Save XMP metadata */
- pg.save_xmp = toggle =
- gtk_check_button_new_with_mnemonic (_("Save _XMP data"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.save_xmp);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.save_xmp);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- /* Save IPTC metadata */
- pg.save_iptc = toggle =
- gtk_check_button_new_with_mnemonic (_("Save _IPTC data"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.save_iptc);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.save_iptc);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- /* Save thumbnail */
- pg.save_thumbnail = toggle =
- gtk_check_button_new_with_mnemonic (_("Save _thumbnail"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.save_thumbnail);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.save_thumbnail);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- /* Save color profile */
- pg.save_profile = toggle =
- gtk_check_button_new_with_mnemonic (_("Save color _profile"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.save_profile);
- gtk_box_pack_start (GTK_BOX (vbox2), toggle, FALSE, FALSE, 0);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.save_profile);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
- /* Comment */
- frame = gimp_frame_new (_("Comment"));
- gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
- gtk_widget_show (frame);
-
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (scrolled_window, 250, 50);
- gtk_container_add (GTK_CONTAINER (frame), scrolled_window);
- gtk_widget_show (scrolled_window);
-
- pg.text_buffer = text_buffer = gtk_text_buffer_new (NULL);
- if (image_comment)
- gtk_text_buffer_set_text (text_buffer, image_comment, -1);
-
- text_view = gtk_text_view_new_with_buffer (text_buffer);
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
-
- gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
- gtk_widget_show (text_view);
-
- g_object_unref (text_buffer);
-
- /* Advanced expander */
- text = g_strdup_printf ("<b>%s</b>", _("_Advanced Options"));
- expander = gtk_expander_new_with_mnemonic (text);
- gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
- g_free (text);
-
- gtk_box_pack_start (GTK_BOX (vbox), expander, TRUE, TRUE, 0);
- gtk_widget_show (expander);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_add (GTK_CONTAINER (expander), vbox);
- gtk_widget_show (vbox);
-
- frame = gimp_frame_new ("<expander>");
- gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
- gtk_widget_show (frame);
-
- grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
- gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
- gtk_container_add (GTK_CONTAINER (frame), grid);
- gtk_widget_show (grid);
-
- pg.smoothing = gimp_scale_entry_new (_("S_moothing:"), jsvals.smoothing, 0.0, 1.0, 2);
- gimp_help_set_help_data (pg.smoothing, NULL, "file-jpeg-save-smoothing");
- g_signal_connect (pg.smoothing, "value-changed",
- G_CALLBACK (scale_entry_update),
- &jsvals.smoothing);
- g_signal_connect (pg.smoothing, "value-changed",
- G_CALLBACK (make_preview),
- NULL);
- gtk_grid_attach (GTK_GRID (grid), pg.smoothing, 2, 0, 4, 1);
- gtk_widget_show (pg.smoothing);
-
- restart_markers_label = gtk_label_new (_("Interval (MCU rows):"));
- gtk_label_set_xalign (GTK_LABEL (restart_markers_label), 1.0);
- gtk_grid_attach (GTK_GRID (grid), restart_markers_label, 4, 1, 1, 1);
- gtk_widget_show (restart_markers_label);
-
- pg.scale_data = gtk_adjustment_new (((jsvals.restart == 0) ?
- DEFAULT_RESTART_MCU_ROWS : jsvals.restart),
- 1.0, 64.0, 1.0, 1.0, 0);
- pg.restart = restart_markers_scale = spinbutton =
- gimp_spin_button_new (pg.scale_data, 1.0, 0);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
- gtk_grid_attach (GTK_GRID (grid), spinbutton, 5, 1, 1, 1);
- gtk_widget_show (spinbutton);
-
- pg.use_restart_markers = toggle =
- gtk_check_button_new_with_mnemonic (_("Use _restart markers"));
- gtk_grid_attach (GTK_GRID (grid), toggle, 2, 1, 2, 1);
- gtk_widget_show (toggle);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.restart);
-
- gtk_widget_set_sensitive (restart_markers_label, jsvals.restart);
- gtk_widget_set_sensitive (restart_markers_scale, jsvals.restart);
-
- g_signal_connect (pg.scale_data, "value-changed",
- G_CALLBACK (save_restart_update),
- toggle);
- pg.handler_id_restart = g_signal_connect_swapped (toggle, "toggled",
- G_CALLBACK (save_restart_update),
- pg.scale_data);
-
- row = 0;
-
- /* Optimize */
- pg.optimize = toggle = gtk_check_button_new_with_mnemonic (_("_Optimize"));
- gtk_grid_attach (GTK_GRID (grid), toggle, 0, row, 1, 1);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.optimize);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.optimize);
-
- if (arithc_supported)
- gtk_widget_set_sensitive (toggle, !jsvals.arithmetic_coding);
+#ifdef C_ARITH_CODING_SUPPORTED
+ gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
+ "arithmetic-frame", "use-arithmetic-coding", TRUE,
+ "optimize");
+#endif
- row++;
+ /* Restart marker. */
+ /* TODO: apparently when toggle is unchecked, we want to show the
+ * scale as 0.
+ */
+ gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
+ "restart-frame", "use-restart", FALSE,
+ "restart");
+ if (restart == 0)
+ g_object_set (config,
+ "restart", DEFAULT_RESTART_MCU_ROWS,
+ "use-restart", FALSE,
+ NULL);
- if (arithc_supported)
+ /* Subsampling */
+ store = gimp_int_store_new (_("4:4:4 (best quality)"),
+ JPEG_SUBSAMPLING_1x1_1x1_1x1,
+ _("4:2:2 horizontal (chroma halved)"),
+ JPEG_SUBSAMPLING_2x1_1x1_1x1,
+ _("4:2:2 vertical (chroma halved)"),
+ JPEG_SUBSAMPLING_1x2_1x1_1x1,
+ _("4:2:0 (chroma quartered)"),
+ JPEG_SUBSAMPLING_2x2_1x1_1x1,
+ NULL);
+ widget = gimp_procedure_dialog_get_int_combo (GIMP_PROCEDURE_DIALOG (dialog),
+ "sub-sampling", GIMP_INT_STORE (store));
+ widget = gimp_label_int_widget_get_widget (GIMP_LABEL_INT_WIDGET (widget));
+ g_object_unref (store);
+
+ if (! gimp_drawable_is_rgb (drawable))
{
- /* Arithmetic coding */
- pg.arithmetic_coding = toggle = gtk_check_button_new_with_mnemonic
- (_("Use arithmetic _coding"));
- gtk_widget_set_tooltip_text
- (toggle, _("Older software may have trouble opening "
- "arithmetic-coded images"));
- gtk_grid_attach (GTK_GRID (grid), toggle, 0, row, 1, 1);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.arithmetic_coding);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (toggle_arithmetic_coding),
- pg.optimize);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
- jsvals.arithmetic_coding);
-
- row++;
+ g_object_set (config, "sub-sampling", JPEG_SUBSAMPLING_1x1_1x1_1x1, NULL);
+ gtk_widget_set_sensitive (widget, FALSE);
}
- /* Progressive */
- pg.progressive = toggle =
- gtk_check_button_new_with_mnemonic (_("_Progressive"));
- gtk_grid_attach (GTK_GRID (grid), toggle, 0, row, 1, 1);
- gtk_widget_show (toggle);
-
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (gimp_toggle_button_update),
- &jsvals.progressive);
- g_signal_connect (toggle, "toggled",
- G_CALLBACK (make_preview),
- NULL);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
- jsvals.progressive);
-
- row++;
-
- /* Subsampling */
- label = gtk_label_new_with_mnemonic (_("Su_bsampling:"));
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gtk_grid_attach (GTK_GRID (grid), label, 2, 2, 1, 1);
- gtk_widget_show (label);
-
- pg.subsmp =
- combo = gimp_int_combo_box_new (_("4:4:4 (best quality)"),
- JPEG_SUBSAMPLING_1x1_1x1_1x1,
- _("4:2:2 horizontal (chroma halved)"),
- JPEG_SUBSAMPLING_2x1_1x1_1x1,
- _("4:2:2 vertical (chroma halved)"),
- JPEG_SUBSAMPLING_1x2_1x1_1x1,
- _("4:2:0 (chroma quartered)"),
- JPEG_SUBSAMPLING_2x2_1x1_1x1,
- NULL);
- gtk_grid_attach (GTK_GRID (grid), combo, 3, 2, 3, 1);
- gtk_widget_show (combo);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
-
+ /* DCT method */
+ store = gimp_int_store_new (_("Fast Integer"), 1,
+ _("Integer"), 0,
+ _("Floating-Point"), 2,
+ NULL);
+ gimp_procedure_dialog_get_int_combo (GIMP_PROCEDURE_DIALOG (dialog),
+ "dct", GIMP_INT_STORE (store));
+ g_object_unref (store);
+
+ gimp_procedure_dialog_get_label (GIMP_PROCEDURE_DIALOG (dialog),
+ "advanced-title", _("Advanced Options"));
+ widget = gimp_procedure_dialog_get_widget (GIMP_PROCEDURE_DIALOG (dialog),
+ "smoothing", GIMP_TYPE_SCALE_ENTRY);
+ gimp_help_set_help_data (widget, NULL, "file-jpeg-save-smoothing");
+
+ /* Add some logics for "Use original quality". */
if (gimp_drawable_is_rgb (drawable))
{
- gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
- jsvals.subsmp,
- G_CALLBACK (subsampling_changed),
- pg.smoothing, NULL);
- g_signal_connect (pg.subsmp, "changed",
- G_CALLBACK (subsampling_changed2),
- pg.use_orig_quality);
- g_signal_connect (pg.use_orig_quality, "toggled",
- G_CALLBACK (use_orig_qual_changed2),
- pg.subsmp);
+ g_signal_connect (config, "notify::sub-sampling",
+ G_CALLBACK (subsampling_changed),
+ widget);
+ subsampling_changed (config, NULL, widget);
+ g_signal_connect (config, "notify::use-original-quality",
+ G_CALLBACK (use_orig_qual_changed_rgb),
+ NULL);
}
- else
- {
- gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo),
- JPEG_SUBSAMPLING_1x1_1x1_1x1);
- gtk_widget_set_sensitive (combo, FALSE);
- }
+ gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
+ "advanced-options",
+ "smoothing",
+ "progressive",
+#ifdef C_ARITH_CODING_SUPPORTED
+ "arithmetic-frame",
+#else
+ "optimize",
+#endif
+ "restart-frame",
+ "sub-sampling",
+ "dct",
+ NULL);
+ gimp_procedure_dialog_fill_frame (GIMP_PROCEDURE_DIALOG (dialog),
+ "advanced-frame", "advanced-title", FALSE,
+ "advanced-options");
+
+ gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog),
+ "quality", "use-original-quality",
+ "preview-size", "show-preview",
+ "advanced-frame",
+ NULL);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
- /* DCT method */
- label = gtk_label_new_with_mnemonic (_("_DCT method:"));
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gtk_grid_attach (GTK_GRID (grid), label, 2, 3, 1, 1);
- gtk_widget_show (label);
-
- pg.dct = combo = gimp_int_combo_box_new (_("Fast Integer"), 1,
- _("Integer"), 0,
- _("Floating-Point"), 2,
- NULL);
- gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), jsvals.dct);
- gtk_grid_attach (GTK_GRID (grid), combo, 3, 3, 3, 1);
- gtk_widget_show (combo);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
-
- g_signal_connect (combo, "changed",
- G_CALLBACK (gimp_int_combo_box_get_active),
- &jsvals.dct);
- g_signal_connect (combo, "changed",
+ /* Run make_preview() when various config are changed. */
+ g_signal_connect (config, "notify",
G_CALLBACK (make_preview),
NULL);
- /* Load/Save defaults */
- griddefaults = gtk_grid_new ();
- gtk_container_set_border_width (GTK_CONTAINER (griddefaults), 12);
- gtk_grid_set_column_spacing (GTK_GRID (griddefaults), 6);
- gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
- griddefaults, FALSE, FALSE, 0);
- gtk_widget_show (griddefaults);
-
- button = gtk_button_new_with_mnemonic (_("_Load Defaults"));
- gtk_grid_attach (GTK_GRID (griddefaults), button, 0, 1, 1, 1);
- gtk_widget_show (button);
-
- g_signal_connect_swapped (button, "clicked",
- G_CALLBACK (load_gui_defaults),
- &pg);
-
- button = gtk_button_new_with_mnemonic (_("Sa_ve Defaults"));
- gtk_grid_attach (GTK_GRID (griddefaults), button, 1, 1, 1, 1);
- gtk_widget_show (button);
-
- g_signal_connect_swapped (button, "clicked",
- G_CALLBACK (save_defaults),
- &pg);
-
- gtk_widget_show (dialog);
-
- make_preview ();
-
- pg.run = FALSE;
+ make_preview (config);
- gtk_main ();
+ run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
destroy_preview ();
- return pg.run;
-}
-
-static void
-save_dialog_response (GtkWidget *widget,
- gint response_id,
- gpointer data)
-{
- JpegSaveGui *pg = data;
- GtkTextIter start_iter;
- GtkTextIter end_iter;
-
- switch (response_id)
- {
- case GTK_RESPONSE_OK:
- gtk_text_buffer_get_bounds (pg->text_buffer, &start_iter, &end_iter);
- image_comment = gtk_text_buffer_get_text (pg->text_buffer,
- &start_iter, &end_iter, FALSE);
- pg->run = TRUE;
- /* fallthrough */
-
- default:
- gtk_widget_destroy (widget);
- break;
- }
-}
-
-void
-load_defaults (void)
-{
- jsvals.quality = DEFAULT_IJG_QUALITY;
- jsvals.smoothing = DEFAULT_SMOOTHING;
- jsvals.optimize = DEFAULT_OPTIMIZE;
- jsvals.arithmetic_coding= DEFAULT_ARITHMETIC_CODING;
- jsvals.progressive = DEFAULT_PROGRESSIVE;
- jsvals.baseline = DEFAULT_BASELINE;
- jsvals.subsmp = DEFAULT_SUBSMP;
- jsvals.restart = DEFAULT_RESTART;
- jsvals.dct = DEFAULT_DCT;
- jsvals.preview = DEFAULT_PREVIEW;
- jsvals.save_exif = DEFAULT_EXIF;
- jsvals.save_xmp = DEFAULT_XMP;
- jsvals.save_iptc = DEFAULT_IPTC;
- jsvals.save_thumbnail = DEFAULT_THUMBNAIL;
- jsvals.save_profile = DEFAULT_PROFILE;
- jsvals.use_orig_quality = DEFAULT_USE_ORIG_QUALITY;
-}
-
-void
-load_parasite (void)
-{
- GimpParasite *parasite;
- gchar *def_str;
- JpegSaveVals tmpvals;
- gint num_fields;
- gint subsampling;
-
- parasite = gimp_get_parasite (JPEG_DEFAULTS_PARASITE);
-
- if (! parasite)
- return;
-
- def_str = g_strndup (gimp_parasite_data (parasite),
- gimp_parasite_data_size (parasite));
-
- gimp_parasite_free (parasite);
-
- /* Initialize tmpvals in case fewer fields exist in the parasite
- (e.g., when importing from a previous version of GIMP). */
- memcpy(&tmpvals, &jsvals, sizeof jsvals);
-
- num_fields = sscanf (def_str,
- "%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
- &tmpvals.quality,
- &tmpvals.smoothing,
- &tmpvals.optimize,
- &tmpvals.progressive,
- &subsampling,
- &tmpvals.baseline,
- &tmpvals.restart,
- &tmpvals.dct,
- &tmpvals.preview,
- &tmpvals.save_exif,
- &tmpvals.save_thumbnail,
- &tmpvals.save_xmp,
- &tmpvals.use_orig_quality,
- &tmpvals.save_iptc,
- &tmpvals.arithmetic_coding,
- &tmpvals.save_profile);
-
- tmpvals.subsmp = subsampling;
-
- if (num_fields == 13 || num_fields == 15 || num_fields == 16)
- {
- memcpy (&jsvals, &tmpvals, sizeof (tmpvals));
- }
-
- g_free (def_str);
+ return run;
}
static void
-save_defaults (void)
+quality_changed (GimpProcedureConfig *config)
{
- GimpParasite *parasite;
- gchar *def_str;
-
- def_str = g_strdup_printf ("%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
- jsvals.quality,
- jsvals.smoothing,
- jsvals.optimize,
- jsvals.progressive,
- (gint) jsvals.subsmp,
- jsvals.baseline,
- jsvals.restart,
- jsvals.dct,
- jsvals.preview,
- jsvals.save_exif,
- jsvals.save_thumbnail,
- jsvals.save_xmp,
- jsvals.use_orig_quality,
- jsvals.save_iptc,
- jsvals.arithmetic_coding,
- jsvals.save_profile);
- parasite = gimp_parasite_new (JPEG_DEFAULTS_PARASITE,
- GIMP_PARASITE_PERSISTENT,
- strlen (def_str), def_str);
-
- gimp_attach_parasite (parasite);
-
- gimp_parasite_free (parasite);
- g_free (def_str);
+ gboolean use_orig_quality;
+ gdouble quality;
+ gint orig_quality;
+
+ g_object_get (config,
+ "use-original-quality", &use_orig_quality,
+ "original-quality", &orig_quality,
+ "quality", &quality,
+ NULL);
+
+ if (use_orig_quality && (gint) (quality * 100.0) != orig_quality)
+ g_object_set (config, "use-original-quality", FALSE, NULL);
}
static void
-load_gui_defaults (JpegSaveGui *pg)
+subsampling_changed (GimpProcedureConfig *config,
+ const GParamSpec *pspec,
+ GtkWidget *smoothing_scale)
{
- GtkAdjustment *restart_markers;
-
- load_defaults ();
- load_parasite ();
-
-#define SET_ACTIVE_BTTN(field) \
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pg->field), jsvals.field)
-
- SET_ACTIVE_BTTN (optimize);
- SET_ACTIVE_BTTN (progressive);
- SET_ACTIVE_BTTN (use_orig_quality);
- SET_ACTIVE_BTTN (preview);
- SET_ACTIVE_BTTN (save_exif);
- SET_ACTIVE_BTTN (save_xmp);
- SET_ACTIVE_BTTN (save_iptc);
- SET_ACTIVE_BTTN (save_thumbnail);
- SET_ACTIVE_BTTN (save_profile);
-
-#undef SET_ACTIVE_BTTN
-
-/*spin button stuff*/
- g_signal_handler_block (pg->use_restart_markers, pg->handler_id_restart);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pg->use_restart_markers),
- jsvals.restart);
- restart_markers = pg->scale_data;
- gtk_adjustment_set_value (restart_markers, jsvals.restart);
- g_signal_handler_unblock (pg->use_restart_markers, pg->handler_id_restart);
-
- gimp_label_spin_set_value (GIMP_LABEL_SPIN (pg->smoothing), jsvals.smoothing);
-
- /* Don't override quality and subsampling setting if we already set it from original */
- if (!jsvals.use_orig_quality)
- {
- gimp_label_spin_set_value (GIMP_LABEL_SPIN (pg->quality), jsvals.quality);
-
- if (gimp_drawable_is_rgb (drawable_global))
- {
- gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (pg->subsmp),
- jsvals.subsmp);
- }
- }
+ gboolean use_orig_quality;
+ gint orig_subsmp;
+ gint subsmp;
- gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (pg->dct),
- jsvals.dct);
-}
+ g_object_get (config,
+ "use-original-quality", &use_orig_quality,
+ "original-sub-sampling", &orig_subsmp,
+ "sub-sampling", &subsmp,
+ NULL);
-static void
-scale_entry_update (GimpLabelSpin *entry,
- gdouble *value)
-{
- *value = gimp_label_spin_get_value (entry);
-}
-
-static void
-save_restart_update (GtkAdjustment *adjustment,
- GtkWidget *toggle)
-{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
- jsvals.restart = gtk_adjustment_get_value (adjustment);
- else
- jsvals.restart = 0;
-
- gtk_widget_set_sensitive (restart_markers_label, jsvals.restart);
- gtk_widget_set_sensitive (restart_markers_scale, jsvals.restart);
+ /* smoothing is not supported with nonstandard sampling ratios */
+ gtk_widget_set_sensitive (smoothing_scale,
+ subsmp != JPEG_SUBSAMPLING_2x1_1x1_1x1 &&
+ subsmp != JPEG_SUBSAMPLING_1x2_1x1_1x1);
- make_preview ();
+ if (use_orig_quality && orig_subsmp != subsmp)
+ g_object_set (config, "use-original-quality", FALSE, NULL);
}
static void
-subsampling_changed (GtkWidget *combo,
- GtkWidget *entry)
+use_orig_qual_changed (GimpProcedureConfig *config)
{
- gint value;
-
- gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (combo), &value);
+ gboolean use_orig_quality;
+ gint orig_quality;
- jsvals.subsmp = value;
+ g_object_get (config,
+ "use-original-quality", &use_orig_quality,
+ "original-quality", &orig_quality,
+ NULL);
- /* smoothing is not supported with nonstandard sampling ratios */
- gtk_widget_set_sensitive (entry,
- jsvals.subsmp != JPEG_SUBSAMPLING_2x1_1x1_1x1 &&
- jsvals.subsmp != JPEG_SUBSAMPLING_1x2_1x1_1x1);
-
- make_preview ();
-}
-
-static void
-quality_changed (GimpScaleEntry *scale_entry,
- GtkWidget *toggle)
-{
- if (jsvals.use_orig_quality)
+ if (use_orig_quality && orig_quality > 0)
{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
+ g_signal_handlers_block_by_func (config, quality_changed, NULL);
+ g_object_set (config, "quality", orig_quality / 100.0, NULL);
+ g_signal_handlers_unblock_by_func (config, quality_changed, NULL);
}
}
static void
-subsampling_changed2 (GtkWidget *combo,
- GtkWidget *toggle)
+use_orig_qual_changed_rgb (GimpProcedureConfig *config)
{
- if (jsvals.use_orig_quality && orig_subsmp != jsvals.subsmp)
- {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
- }
-}
+ gboolean use_orig_quality;
+ gint orig_quality;
+ gint orig_subsmp;
-static void
-use_orig_qual_changed (GtkWidget *toggle,
- GimpLabelSpin *scale_entry)
-{
- if (jsvals.use_orig_quality && orig_quality > 0)
- {
- g_signal_handlers_block_by_func (scale_entry, quality_changed, toggle);
- gimp_label_spin_set_value (scale_entry, orig_quality);
- g_signal_handlers_unblock_by_func (scale_entry, quality_changed, toggle);
- }
-}
+ g_object_get (config,
+ "use-original-quality", &use_orig_quality,
+ "original-sub-sampling", &orig_subsmp,
+ "original-quality", &orig_quality,
+ NULL);
-static void
-use_orig_qual_changed2 (GtkWidget *toggle,
- GtkWidget *combo)
-{
/* the test is (orig_quality > 0), not (orig_subsmp > 0) - this is normal */
- if (jsvals.use_orig_quality && orig_quality > 0)
- {
- gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), orig_subsmp);
- }
+ if (use_orig_quality && orig_quality > 0)
+ g_object_set (config, "sub-sampling", orig_subsmp, NULL);
}
diff --git a/plug-ins/file-jpeg/jpeg-save.h b/plug-ins/file-jpeg/jpeg-save.h
index c5fd590ffe..14acc47864 100644
--- a/plug-ins/file-jpeg/jpeg-save.h
+++ b/plug-ins/file-jpeg/jpeg-save.h
@@ -18,40 +18,20 @@
#ifndef __JPEG_SAVE_H__
#define __JPEG_SAVE_H__
-typedef struct
-{
- gdouble quality;
- gdouble smoothing;
- gboolean optimize;
- gboolean arithmetic_coding;
- gboolean progressive;
- gboolean baseline;
- JpegSubsampling subsmp;
- gint restart;
- gint dct;
- gboolean preview;
- gboolean save_exif;
- gboolean save_xmp;
- gboolean save_iptc;
- gboolean save_thumbnail;
- gboolean save_profile;
- gboolean use_orig_quality;
-} JpegSaveVals;
-
-extern JpegSaveVals jsvals;
extern GimpImage *orig_image_global;
extern GimpDrawable *drawable_global;
-gboolean save_image (GFile *file,
- GimpImage *image,
- GimpDrawable *drawable,
- GimpImage *orig_image,
- gboolean preview,
- GError **error);
-gboolean save_dialog (GimpDrawable *drawable);
-void load_defaults (void);
-void load_parasite (void);
+gboolean save_image (GFile *file,
+ GimpProcedureConfig *config,
+ GimpImage *image,
+ GimpDrawable *drawable,
+ GimpImage *orig_image,
+ gboolean preview,
+ GError **error);
+gboolean save_dialog (GimpProcedure *procedure,
+ GimpProcedureConfig *config,
+ GimpDrawable *drawable);
#endif /* __JPEG_SAVE_H__ */
diff --git a/plug-ins/file-jpeg/jpeg-settings.c b/plug-ins/file-jpeg/jpeg-settings.c
index ed80db4f81..dbd1264db8 100644
--- a/plug-ins/file-jpeg/jpeg-settings.c
+++ b/plug-ins/file-jpeg/jpeg-settings.c
@@ -208,7 +208,7 @@ jpeg_restore_original_settings (GimpImage *image,
*num_quant_tables = -1;
/* the current plug-in can only use subsampling for YCbCr (3) */
- *subsmp = -1;
+ *subsmp = JPEG_SUBSAMPLING_1x1_1x1_1x1;
if (num_components == 3)
{
h[0] = *src++;
@@ -240,7 +240,7 @@ jpeg_restore_original_settings (GimpImage *image,
}
*quality = -1;
- *subsmp = -1;
+ *subsmp = JPEG_SUBSAMPLING_1x1_1x1_1x1;
*num_quant_tables = 0;
return FALSE;
diff --git a/plug-ins/file-jpeg/jpeg.c b/plug-ins/file-jpeg/jpeg.c
index bcae891e88..b697d3bbc6 100644
--- a/plug-ins/file-jpeg/jpeg.c
+++ b/plug-ins/file-jpeg/jpeg.c
@@ -84,14 +84,9 @@ GIMP_MAIN (JPEG_TYPE)
gboolean undo_touched = FALSE;
-gchar *image_comment = NULL;
GimpDisplay *display = NULL;
-JpegSaveVals jsvals = { 0, };
GimpImage *orig_image_global = NULL;
GimpDrawable *drawable_global = NULL;
-gint orig_quality = 0;
-JpegSubsampling orig_subsmp = JPEG_SUBSAMPLING_2x2_1x1_1x1;;
-gint num_quant_tables = 0;
static void
@@ -201,13 +196,13 @@ jpeg_create_procedure (GimpPlugIn *plug_in,
*/
GIMP_PROC_ARG_DOUBLE (procedure, "quality",
"Quality",
- "Quality of saved image",
+ "Quality of exported image",
0.0, 1.0, 0.9,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DOUBLE (procedure, "smoothing",
- "Smoothing",
- "Smoothing factor for saved image",
+ "S_moothing",
+ "Smoothing factor for exported image",
0.0, 1.0, 0.0,
G_PARAM_READWRITE);
@@ -218,19 +213,13 @@ jpeg_create_procedure (GimpPlugIn *plug_in,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "progressive",
- "Progressive",
+ "_Progressive",
"Create progressive JPEG images",
TRUE,
G_PARAM_READWRITE);
- GIMP_PROC_ARG_STRING (procedure, "comment",
- "Comment",
- "Image comment",
- gimp_get_default_comment (),
- G_PARAM_READWRITE);
-
GIMP_PROC_ARG_INT (procedure, "sub-sampling",
- "Sub-sampling",
+ _("Su_bsampling"),
"Sub-sampling type { 0 == 4:2:0 (chroma quartered), "
"1 == 4:2:2 Horizontal (chroma halved), "
"2 == 4:4:4 (best quality), "
@@ -248,18 +237,66 @@ jpeg_create_procedure (GimpPlugIn *plug_in,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "restart",
- "Restart",
+ _("Interval (MCU rows):"),
"Interval of restart markers "
"(in MCU rows, 0 = no restart markers)",
0, 64, 0,
G_PARAM_READWRITE);
GIMP_PROC_ARG_INT (procedure, "dct",
- "DCT",
+ _("_DCT method"),
"DCT method to use { INTEGER (0), FIXED (1), "
"FLOAT (2) }",
0, 2, 0,
G_PARAM_READWRITE);
+
+ /* Some auxiliary arguments mostly for interactive usage. */
+
+ GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "use-original-quality",
+ "_Use quality settings from original image",
+ "If the original image was loaded from a JPEG "
+ "file using non-standard quality settings "
+ "(quantization tables), enable this option to "
+ "get almost the same quality and file size.",
+ FALSE,
+ G_PARAM_READWRITE);
+ GIMP_PROC_AUX_ARG_INT (procedure, "original-quality",
+ NULL, NULL,
+ -1, 100, -1,
+ G_PARAM_READWRITE);
+ GIMP_PROC_AUX_ARG_INT (procedure, "original-sub-sampling",
+ NULL, NULL,
+ JPEG_SUBSAMPLING_2x2_1x1_1x1,
+ JPEG_SUBSAMPLING_1x2_1x1_1x1,
+ JPEG_SUBSAMPLING_2x2_1x1_1x1,
+ G_PARAM_READWRITE);
+ GIMP_PROC_AUX_ARG_INT (procedure, "original-num-quant-tables",
+ NULL, NULL,
+ -1, 4, -1,
+ G_PARAM_READWRITE);
+
+ GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "show-preview",
+ "Sho_w preview in image window",
+ "Creates a temporary layer with an export preview",
+ FALSE,
+ G_PARAM_READWRITE);
+ GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "use-arithmetic-coding",
+ "Use arithmetic _coding",
+ _("Older software may have trouble opening "
+ "arithmetic-coded images"),
+ FALSE,
+ G_PARAM_READWRITE);
+ GIMP_PROC_AUX_ARG_BOOLEAN (procedure, "use-restart",
+ _("Use _restart markers"),
+ NULL, FALSE,
+ G_PARAM_READWRITE);
+
+ gimp_save_procedure_set_support_exif (GIMP_SAVE_PROCEDURE (procedure), TRUE);
+ gimp_save_procedure_set_support_iptc (GIMP_SAVE_PROCEDURE (procedure), TRUE);
+ gimp_save_procedure_set_support_xmp (GIMP_SAVE_PROCEDURE (procedure), TRUE);
+ gimp_save_procedure_set_support_profile (GIMP_SAVE_PROCEDURE (procedure), TRUE);
+ gimp_save_procedure_set_support_thumbnail (GIMP_SAVE_PROCEDURE (procedure), TRUE);
+ gimp_save_procedure_set_support_comment (GIMP_SAVE_PROCEDURE (procedure), TRUE);
}
return procedure;
@@ -385,16 +422,22 @@ jpeg_save (GimpProcedure *procedure,
gpointer run_data)
{
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
- GimpParasite *parasite;
+ GimpProcedureConfig *config;
GimpMetadata *metadata;
- GimpMetadataSaveFlags metadata_flags;
GimpImage *orig_image;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GError *error = NULL;
+ gint orig_num_quant_tables = -1;
+ gint orig_quality = -1;
+ JpegSubsampling orig_subsmp = JPEG_SUBSAMPLING_2x2_1x1_1x1;
+
INIT_I18N ();
gegl_init (NULL, NULL);
+ config = gimp_procedure_create_config (procedure);
+ metadata = gimp_procedure_config_begin_export (config, image, run_mode,
+ args, "image/jpeg");
preview_image = NULL;
preview_layer = NULL;
@@ -453,118 +496,77 @@ jpeg_save (GimpProcedure *procedure,
error);
}
- /* Initialize with hardcoded defaults */
- load_defaults ();
-
- /* Override the defaults with preferences. */
- metadata = gimp_image_metadata_save_prepare (orig_image,
- "image/jpeg",
- &metadata_flags);
- jsvals.save_exif = (metadata_flags & GIMP_METADATA_SAVE_EXIF) != 0;
- jsvals.save_xmp = (metadata_flags & GIMP_METADATA_SAVE_XMP) != 0;
- jsvals.save_iptc = (metadata_flags & GIMP_METADATA_SAVE_IPTC) != 0;
- jsvals.save_thumbnail = (metadata_flags & GIMP_METADATA_SAVE_THUMBNAIL) != 0;
- jsvals.save_profile = (metadata_flags & GIMP_METADATA_SAVE_COLOR_PROFILE) != 0;
-
- parasite = gimp_image_get_parasite (orig_image, "gimp-comment");
- if (parasite)
- {
- image_comment = g_strndup (gimp_parasite_data (parasite),
- gimp_parasite_data_size (parasite));
- gimp_parasite_free (parasite);
- }
-
/* Override preferences from JPG export defaults (if saved). */
- load_parasite ();
switch (run_mode)
{
case GIMP_RUN_NONINTERACTIVE:
- g_free (image_comment);
-
- jsvals.quality = GIMP_VALUES_GET_DOUBLE (args, 0) * 100.0;
- jsvals.smoothing = GIMP_VALUES_GET_DOUBLE (args, 1);
- jsvals.optimize = GIMP_VALUES_GET_BOOLEAN (args, 2);
- jsvals.progressive = GIMP_VALUES_GET_BOOLEAN (args, 3);
- image_comment = GIMP_VALUES_DUP_STRING (args, 4);
- jsvals.subsmp = GIMP_VALUES_GET_DOUBLE (args, 5);
- jsvals.baseline = GIMP_VALUES_GET_DOUBLE (args, 6);
- jsvals.restart = GIMP_VALUES_GET_DOUBLE (args, 7);
- jsvals.dct = GIMP_VALUES_GET_DOUBLE (args, 8);
- jsvals.preview = FALSE;
+ g_object_set (config, "show-preview", FALSE, NULL);
break;
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
- /* restore the values found when loading the file (if available) */
- jpeg_restore_original_settings (orig_image,
- &orig_quality,
- &orig_subsmp,
- &num_quant_tables);
-
- /* load up the previously used values (if file was saved once) */
- parasite = gimp_image_get_parasite (orig_image,
- "jpeg-save-options");
- if (parasite)
{
- const JpegSaveVals *save_vals = gimp_parasite_data (parasite);
-
- jsvals.quality = save_vals->quality;
- jsvals.smoothing = save_vals->smoothing;
- jsvals.optimize = save_vals->optimize;
- jsvals.progressive = save_vals->progressive;
- jsvals.baseline = save_vals->baseline;
- jsvals.subsmp = save_vals->subsmp;
- jsvals.restart = save_vals->restart;
- jsvals.dct = save_vals->dct;
- jsvals.preview = save_vals->preview;
- jsvals.save_exif = save_vals->save_exif;
- jsvals.save_thumbnail = save_vals->save_thumbnail;
- jsvals.save_xmp = save_vals->save_xmp;
- jsvals.save_iptc = save_vals->save_iptc;
- jsvals.use_orig_quality = save_vals->use_orig_quality;
-
- gimp_parasite_free (parasite);
- }
- else
- {
- /* We are called with GIMP_RUN_WITH_LAST_VALS but this image
- * doesn't have a "jpeg-save-options" parasite. It's better
- * to prompt the user with a dialog now so that she has
- * control over the JPEG encoding parameters.
- */
- run_mode = GIMP_RUN_INTERACTIVE;
+ /* restore the values found when loading the file (if available) */
+ gdouble dquality;
+ gint quality;
+ gint subsmp;
+
+ jpeg_restore_original_settings (orig_image,
+ &orig_quality,
+ &orig_subsmp,
+ &orig_num_quant_tables);
+
+ g_object_get (config,
+ "quality", &dquality,
+ "sub-sampling", &subsmp,
+ NULL);
+
+ quality = (gint) (dquality * 100.0);
/* If this image was loaded from a JPEG file and has not
* been saved yet, try to use some of the settings from the
* original file if they are better than the default values.
*/
- if (orig_quality > jsvals.quality)
+ if (orig_quality > quality)
{
- jsvals.quality = orig_quality;
+ quality = orig_quality;
+ dquality = (gdouble) quality / 100.0;
+ g_object_set (config, "quality", dquality, NULL);
}
- /* Skip changing subsampling to original if we already have
- * best setting or if original have worst setting
- */
- if (!(jsvals.subsmp == JPEG_SUBSAMPLING_1x1_1x1_1x1 ||
- orig_subsmp == JPEG_SUBSAMPLING_2x2_1x1_1x1))
+ if (orig_quality > 0)
{
- jsvals.subsmp = orig_subsmp;
- }
+ /* Skip changing subsampling to original if we already have
+ * best setting or if original have worst setting
+ */
+ if (!(subsmp == JPEG_SUBSAMPLING_1x1_1x1_1x1 ||
+ orig_subsmp == JPEG_SUBSAMPLING_2x2_1x1_1x1))
+ {
+ subsmp = orig_subsmp;
+ g_object_set (config, "sub-sampling", orig_subsmp, NULL);
+ }
- if (orig_quality == jsvals.quality &&
- orig_subsmp == jsvals.subsmp)
- {
- jsvals.use_orig_quality = TRUE;
+ if (orig_quality == quality && orig_subsmp == subsmp)
+ {
+ g_object_set (config, "use-original-quality", TRUE, NULL);
+ }
}
}
break;
}
+ g_object_set (config,
+ "original-sub-sampling", orig_subsmp,
+ "original-quality", orig_quality,
+ "original-num-quant-tables", orig_num_quant_tables,
+ NULL);
if (run_mode == GIMP_RUN_INTERACTIVE)
{
- if (jsvals.preview)
+ gboolean show_preview = FALSE;
+
+ g_object_get (config, "show-preview", &show_preview, NULL);
+ if (show_preview)
{
/* we freeze undo saving so that we can avoid sucking up
* tile cache with our unneeded preview steps. */
@@ -579,7 +581,7 @@ jpeg_save (GimpProcedure *procedure,
drawable_global = drawables[0];
/* First acquire information with a dialog */
- if (! save_dialog (drawables[0]))
+ if (! save_dialog (procedure, config, drawables[0]))
{
status = GIMP_PDB_CANCEL;
}
@@ -596,7 +598,8 @@ jpeg_save (GimpProcedure *procedure,
if (status == GIMP_PDB_SUCCESS)
{
- if (! save_image (file, image, drawables[0], orig_image, FALSE,
+ if (! save_image (file, config,
+ image, drawables[0], orig_image, FALSE,
&error))
{
status = GIMP_PDB_EXECUTION_ERROR;
@@ -618,78 +621,12 @@ jpeg_save (GimpProcedure *procedure,
if (status == GIMP_PDB_SUCCESS)
{
- /* pw - now we need to change the defaults to be whatever was
- * used to save this image. Dump the old parasites and add new
- * ones.
- */
-
- gimp_image_detach_parasite (orig_image, "gimp-comment");
- if (image_comment && strlen (image_comment))
- {
- parasite = gimp_parasite_new ("gimp-comment",
- GIMP_PARASITE_PERSISTENT,
- strlen (image_comment) + 1,
- image_comment);
- gimp_image_attach_parasite (orig_image, parasite);
- gimp_parasite_free (parasite);
- }
-
- parasite = gimp_parasite_new ("jpeg-save-options",
- 0, sizeof (jsvals), &jsvals);
- gimp_image_attach_parasite (orig_image, parasite);
- gimp_parasite_free (parasite);
-
- /* write metadata */
-
if (metadata)
- {
- gimp_metadata_set_bits_per_sample (metadata, 8);
-
- if (jsvals.save_exif)
- metadata_flags |= GIMP_METADATA_SAVE_EXIF;
- else
- metadata_flags &= ~GIMP_METADATA_SAVE_EXIF;
-
- if (jsvals.save_xmp)
- metadata_flags |= GIMP_METADATA_SAVE_XMP;
- else
- metadata_flags &= ~GIMP_METADATA_SAVE_XMP;
-
- if (jsvals.save_iptc)
- metadata_flags |= GIMP_METADATA_SAVE_IPTC;
- else
- metadata_flags &= ~GIMP_METADATA_SAVE_IPTC;
-
- if (jsvals.save_thumbnail)
- metadata_flags |= GIMP_METADATA_SAVE_THUMBNAIL;
- else
- metadata_flags &= ~GIMP_METADATA_SAVE_THUMBNAIL;
-
- if (jsvals.save_profile)
- metadata_flags |= GIMP_METADATA_SAVE_COLOR_PROFILE;
- else
- metadata_flags &= ~GIMP_METADATA_SAVE_COLOR_PROFILE;
-
- if (! gimp_image_metadata_save_finish (orig_image,
- "image/jpeg",
- metadata, metadata_flags,
- file, &error))
- {
- if (error)
- {
- /* Even though a failure to write metadata is not enough
- reason to say we failed to save the image, we should
- still notify the user about the problem. */
- g_message ("%s: saving metadata failed: %s",
- G_STRFUNC, error->message);
- g_error_free (error);
- }
- }
- }
+ gimp_metadata_set_bits_per_sample (metadata, 8);
}
- if (metadata)
- g_object_unref (metadata);
+ gimp_procedure_config_end_export (config, image, file, status);
+ g_object_unref (config);
return gimp_procedure_new_return_values (procedure, status, error);
}
diff --git a/plug-ins/file-jpeg/jpeg.h b/plug-ins/file-jpeg/jpeg.h
index ca0710c948..4b8a81d622 100644
--- a/plug-ins/file-jpeg/jpeg.h
+++ b/plug-ins/file-jpeg/jpeg.h
@@ -56,10 +56,6 @@ extern GimpLayer * preview_layer;
extern gboolean undo_touched;
extern gboolean load_interactive;
extern GimpDisplay *display;
-extern gchar *image_comment;
-extern gint orig_quality;
-extern JpegSubsampling orig_subsmp;
-extern gint num_quant_tables;
void destroy_preview (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]