You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ga...@apache.org on 2010/10/21 06:11:16 UTC

svn commit: r1025817 - in /shindig/trunk/java: common/conf/ gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/ gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/

Author: gagan
Date: Thu Oct 21 04:11:16 2010
New Revision: 1025817

URL: http://svn.apache.org/viewvc?rev=1025817&view=rev
Log:
patch from satya3656 | Issue 2322042: Adding Huffmann Size Optimization to Jpeg Compression Params. (gives +(5-7)% of compression) | http://codereview.appspot.com/2322042/

Modified:
    shindig/trunk/java/common/conf/shindig.properties
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/JPEGOptimizer.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfig.java
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/PNGOptimizer.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfigTest.java

Modified: shindig/trunk/java/common/conf/shindig.properties
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/conf/shindig.properties?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/common/conf/shindig.properties (original)
+++ shindig/trunk/java/common/conf/shindig.properties Thu Oct 21 04:11:16 2010
@@ -72,6 +72,10 @@ shindig.image-rewrite.max-palette-size =
 shindig.image-rewrite.allow-jpeg-conversion = true
 shindig.image-rewrite.jpeg-compression = 0.90
 shindig.image-rewrite.min-threshold-bytes = 200
+# Huffman optimization reduces the images size by addition 4-6% without
+# any loss in the quality of the image, but takes extra cpu cycles for
+# computing the optimized huffman tables.
+shindig.image-rewrite.jpeg-huffman-optimization = false
 
 # Configuration for the os:Flash tag
 shindig.flash.min-version = 9.0.115

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/BaseOptimizer.java Thu Oct 21 04:11:16 2010
@@ -26,6 +26,8 @@ import com.google.common.collect.Immutab
 import com.google.common.collect.Maps;
 import com.google.common.base.Objects;
 
+import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
+
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -38,6 +40,7 @@ import javax.imageio.ImageIO;
 import javax.imageio.ImageTypeSpecifier;
 import javax.imageio.ImageWriteParam;
 import javax.imageio.ImageWriter;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
 import javax.imageio.metadata.IIOMetadata;
 
 /**
@@ -74,6 +77,10 @@ abstract class BaseOptimizer {
       if (getOriginalFormatName().equals("jpeg")) {
         param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
         param.setCompressionQuality(config.getJpegCompression());
+        if (param instanceof JPEGImageWriteParam) {
+          ((JPEGImageWriteParam) param).setOptimizeHuffmanTables(
+                config.getJpegHuffmanOptimization());
+        }
       }
       return new ImageIOOutputter(writer, param);
     }
@@ -161,11 +168,26 @@ abstract class BaseOptimizer {
         baos.reset();
       }
       writer.setOutput(ImageIO.createImageOutputStream(baos));
+      
       // Create a new empty metadata set
+      ImageWriteParam metaImageWriteParam = writeParam;
+      if (writer instanceof JPEGImageWriter) {
+        // There is an issue in the javax code because of which function call
+        // writer.getDefaultImageMetadata(new ImageTypeSpecifier(image.getColorModel(),
+        //    image.getSampleModel()), writeParam);
+        //
+        // does buggy processing for compression ratio parameter in ImageWriteParam. 
+        // Hence passing null as ImageWriteParam here to ignore this processing and
+        // passing the ImageWriteParam later in the writer.write() call.
+        metaImageWriteParam = null;
+      }
+
       IIOMetadata metadata = writer.getDefaultImageMetadata(
           new ImageTypeSpecifier(image.getColorModel(), image.getSampleModel()),
-          writeParam);
-      writer.write(new IIOImage(image, Collections.<BufferedImage>emptyList(), metadata));
+          metaImageWriteParam);
+      writer.write(null, new IIOImage(image, Collections.<BufferedImage>emptyList(), metadata),
+                   metaImageWriteParam == null ? writeParam : null);
+
       return baos.toByteArray();
     }
   }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/JPEGOptimizer.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/JPEGOptimizer.java?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/JPEGOptimizer.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/JPEGOptimizer.java Thu Oct 21 04:11:16 2010
@@ -62,7 +62,7 @@ public class JPEGOptimizer extends BaseO
     // Create a new optimizer config and disable JPEG conversion
     OptimizerConfig pngConfig = new OptimizerConfig(config.getMaxInMemoryBytes(),
         config.getMaxPaletteSize(), false, config.getJpegCompression(),
-        config.getMinThresholdBytes());
+        config.getMinThresholdBytes(), config.getJpegHuffmanOptimization());
 
     // Output the image as PNG
     PNGOptimizer pngOptimizer = new PNGOptimizer(pngConfig, response);

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfig.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfig.java?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfig.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfig.java Thu Oct 21 04:11:16 2010
@@ -30,6 +30,7 @@ public class OptimizerConfig {
   private final boolean jpegConversionAllowed;
   private final float jpegCompression;
   private final int minThresholdBytes;
+  private final boolean jpegHuffmanOptimization;
 
   @Inject
   public OptimizerConfig(
@@ -37,7 +38,8 @@ public class OptimizerConfig {
       @Named("shindig.image-rewrite.max-palette-size") int maxPaletteSize,
       @Named("shindig.image-rewrite.allow-jpeg-conversion") boolean jpegConversionAllowed,
       @Named("shindig.image-rewrite.jpeg-compression") float jpegCompression,
-      @Named("shindig.image-rewrite.min-threshold-bytes") int minThresholdBytes) {
+      @Named("shindig.image-rewrite.min-threshold-bytes") int minThresholdBytes,
+      @Named("shindig.image-rewrite.jpeg-huffman-optimization") boolean jpegHuffmanOptimization) {
     this.maxInMemoryBytes = maxInMemoryBytes;
     this.maxPaletteSize = maxPaletteSize;
     this.jpegConversionAllowed = jpegConversionAllowed;
@@ -45,13 +47,14 @@ public class OptimizerConfig {
     // to attempt nor is it too lossy.
     this.jpegCompression = Math.min(0.9f,Math.max(0.5f, jpegCompression));
     this.minThresholdBytes = minThresholdBytes;
+    this.jpegHuffmanOptimization = jpegHuffmanOptimization;
   }
 
   /**
-   * Defaults for usuage in tests.
+   * Defaults for usage in tests.
    */
   public OptimizerConfig() {
-    this(1024 * 1024, 256, true, 0.90f, 200);
+    this(1024 * 1024, 256, true, 0.90f, 200, false);
   }
 
   /**
@@ -92,4 +95,11 @@ public class OptimizerConfig {
   public int getMinThresholdBytes() {
     return minThresholdBytes;
   }
+
+  /**
+   * Indicate if we want to do huffman optimization while enocding the jpeg's.
+   */
+  public boolean getJpegHuffmanOptimization() {
+    return jpegHuffmanOptimization;
+  }
 }

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/PNGOptimizer.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/PNGOptimizer.java?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/PNGOptimizer.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/image/PNGOptimizer.java Thu Oct 21 04:11:16 2010
@@ -89,11 +89,9 @@ class PNGOptimizer extends BaseOptimizer
             bufferedImage.getHeight(),
             BufferedImage.TYPE_INT_RGB);
         rgbOnlyImage.getGraphics().drawImage(bufferedImage, 0, 0, null);
-        ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
-        ImageWriteParam param = writer.getDefaultWriteParam();
-        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
-        param.setCompressionQuality(config.getJpegCompression());
-        outputter = new ImageIOOutputter(writer, param);
+
+        JPEGOptimizer jpegOptimizer = new JPEGOptimizer(config, response);
+        outputter = jpegOptimizer.getOutputter();
         write(rgbOnlyImage);
         // Only use JPEG if it offers a significant reduction over other methods
         if (reductionPct > prevReductionPct + 20) {

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfigTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfigTest.java?rev=1025817&r1=1025816&r2=1025817&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfigTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/image/OptimizerConfigTest.java Thu Oct 21 04:11:16 2010
@@ -29,19 +29,19 @@ public class OptimizerConfigTest {
 
   @Test
   public void testForHighJpegCompression() {
-    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 1.00f, 200);
+    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 1.00f, 200, false);
     assertEquals(0.9f, config.getJpegCompression(), 0.0001);
   }
 
   @Test
   public void testForLowJpegCompression() {
-    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 0.10f, 200);
+    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 0.10f, 200, false);
     assertEquals(0.5f, config.getJpegCompression() , 0.0001);
   }
 
   @Test
   public void testForAcceptableJpegCompression() {
-    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 0.85f, 200);
+    OptimizerConfig config = new OptimizerConfig(1024 * 1024, 256, true, 0.85f, 200, false);
     assertEquals(0.85f, config.getJpegCompression(), 0.0001);
   }
 }