[gimp] file-jpeg: Add support for arithmetic coding



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]