[gimp] file-jpeg: Add support for arithmetic coding
- From: Mukund Sivaraman <muks src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] file-jpeg: Add support for arithmetic coding
- Date: Wed, 14 May 2014 19:28:56 +0000 (UTC)
commit 7a6b8f0e69bfb605ea2b13f99fcae755379604f2
Author: Mukund Sivaraman <muks banu com>
Date: Thu May 15 00:50:30 2014 +0530
file-jpeg: Add support for arithmetic coding
Arithmetic coding is a feature of the JPEG standard. Although libjpeg
had always implemented arithmetic coding, it was compiled out by default
due to patents.
Those patents have now expired.
libjpeg 8 now enables arithmetic coding by default. Distributions which
use libjpeg < 8 can also support arithmetic coding by using the
appropriate CFLAGS to enable it. libjpeg-turbo 1.3.1 also has support
for arithmetic coding and is in popular shipping distributions.
Software such as jpegtran can losslessly convert Huffman compressed
images to arithmetic coding and vice versa. The lossy behavior of JPEG
does not happen at this (bit coding) layer of the format.
This initial patch provides a checkbox (disabled by default) to create
files which use arithmetic coding. It also has a tooltip warning that
such files may not be compatible with older decoders.
plug-ins/file-jpeg/jpeg-save.c | 100 +++++++++++++++++++++++++++++++++++----
plug-ins/file-jpeg/jpeg-save.h | 1 +
2 files changed, 90 insertions(+), 11 deletions(-)
---
diff --git a/plug-ins/file-jpeg/jpeg-save.c b/plug-ins/file-jpeg/jpeg-save.c
index 80e3cf7..054dc3d 100644
--- a/plug-ins/file-jpeg/jpeg-save.c
+++ b/plug-ins/file-jpeg/jpeg-save.c
@@ -51,6 +51,7 @@
#define DEFAULT_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
@@ -95,7 +96,8 @@ typedef struct
GtkObject *quality; /*quality slidebar*/
GtkObject *smoothing; /*smoothing slidebar*/
- GtkWidget *optimize; /*optimize togle*/
+ 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*/
@@ -399,7 +401,13 @@ save_image (const gchar *filename,
}
}
+#ifdef C_ARITH_CODING_SUPPORTED
+ cinfo.arith_code = jsvals.arithmetic_coding;
+ if (!jsvals.arithmetic_coding)
+ cinfo.optimize_coding = jsvals.optimize;
+#else
cinfo.optimize_coding = jsvals.optimize;
+#endif /* C_ARITH_CODING_SUPPORTED */
subsampling = (gimp_drawable_is_rgb (drawable_ID) ?
jsvals.subsmp : JPEG_SUBSAMPLING_1x1_1x1_1x1);
@@ -692,6 +700,17 @@ destroy_preview (void)
}
}
+#ifdef C_ARITH_CODING_SUPPORTED
+static void
+toggle_arithmetic_coding (GtkToggleButton *togglebutton,
+ gpointer user_data)
+{
+ GtkWidget *optimize = GTK_WIDGET (user_data);
+
+ gtk_widget_set_sensitive (optimize, !jsvals.arithmetic_coding);
+}
+#endif /* C_ARITH_CODING_SUPPORTED */
+
gboolean
save_dialog (void)
{
@@ -713,7 +732,7 @@ save_dialog (void)
GtkWidget *scrolled_window;
GtkWidget *button;
gchar *text;
-
+ gint row;
dialog = gimp_export_dialog_new (_("JPEG"), PLUG_IN_BINARY, SAVE_PROC);
@@ -852,8 +871,12 @@ save_dialog (void)
G_CALLBACK (save_restart_update),
pg.scale_data);
+ row = 0;
+
+ /* Optimize */
pg.optimize = toggle = gtk_check_button_new_with_mnemonic (_("_Optimize"));
- gtk_table_attach (GTK_TABLE (table), toggle, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -865,9 +888,43 @@ save_dialog (void)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), jsvals.optimize);
+#ifdef C_ARITH_CODING_SUPPORTED
+ gtk_widget_set_sensitive (toggle, !jsvals.arithmetic_coding);
+#endif /* C_ARITH_CODING_SUPPORTED */
+
+ row++;
+
+#ifdef C_ARITH_CODING_SUPPORTED
+ /* 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_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
+ 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++;
+#endif /* C_ARITH_CODING_SUPPORTED */
+
+ /* Progressive */
pg.progressive = toggle =
gtk_check_button_new_with_mnemonic (_("_Progressive"));
- gtk_table_attach (GTK_TABLE (table), toggle, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -880,10 +937,14 @@ save_dialog (void)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
jsvals.progressive);
+ row++;
+
+ /* 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_table_attach (GTK_TABLE (table), toggle, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -895,10 +956,14 @@ save_dialog (void)
gtk_widget_set_sensitive (toggle, TRUE);
+ row++;
+
+ /* 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_table_attach (GTK_TABLE (table), toggle, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -908,11 +973,14 @@ save_dialog (void)
G_CALLBACK (make_preview),
NULL);
+ row++;
+
/* 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_table_attach (GTK_TABLE (table), toggle, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -924,11 +992,14 @@ save_dialog (void)
gtk_widget_set_sensitive (toggle, TRUE);
+ row++;
+
/* 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_table_attach (GTK_TABLE (table), toggle, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 1,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
@@ -940,11 +1011,14 @@ save_dialog (void)
gtk_widget_set_sensitive (toggle, TRUE);
+ row++;
+
/* 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_table_attach (GTK_TABLE (table), toggle, 0, 4, 6, 7, GTK_FILL, 0, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), toggle, 0, 4,
+ row, row + 1, GTK_FILL, 0, 0, 0);
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
@@ -1145,6 +1219,7 @@ load_defaults (void)
jsvals.quality = DEFAULT_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;
@@ -1167,10 +1242,12 @@ load_defaults (void)
gimp_parasite_free (parasite);
- num_fields = sscanf (def_str, "%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d",
+ num_fields = sscanf (def_str,
+ "%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d",
&tmpvals.quality,
&tmpvals.smoothing,
&tmpvals.optimize,
+ &tmpvals.arithmetic_coding,
&tmpvals.progressive,
&subsampling,
&tmpvals.baseline,
@@ -1199,10 +1276,11 @@ save_defaults (void)
GimpParasite *parasite;
gchar *def_str;
- def_str = g_strdup_printf ("%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d",
+ def_str = g_strdup_printf ("%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d",
jsvals.quality,
jsvals.smoothing,
jsvals.optimize,
+ jsvals.arithmetic_coding,
jsvals.progressive,
(gint) jsvals.subsmp,
jsvals.baseline,
diff --git a/plug-ins/file-jpeg/jpeg-save.h b/plug-ins/file-jpeg/jpeg-save.h
index 2e5ad80..493318e 100644
--- a/plug-ins/file-jpeg/jpeg-save.h
+++ b/plug-ins/file-jpeg/jpeg-save.h
@@ -23,6 +23,7 @@ typedef struct
gdouble quality;
gdouble smoothing;
gboolean optimize;
+ gboolean arithmetic_coding;
gboolean progressive;
gboolean baseline;
JpegSubsampling subsmp;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]