Revision: 7428
Author: [email protected]
Date: Tue Jan 19 07:13:03 2010
Log: Merge tr...@7424.
  Prevent InlineResourceContext from creating too-long data: URLs.
  Disables composition of lossy source images.

$ svn merge -c 7424 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk

http://code.google.com/p/google-web-toolkit/source/detail?r=7428

Added:
 /releases/2.0/user/test/com/google/gwt/resources/client/complexLossy.jpg
Modified:
 /releases/2.0/branch-info.txt
/releases/2.0/user/src/com/google/gwt/resources/client/impl/ImageResourcePrototype.java /releases/2.0/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java
 /releases/2.0/user/src/com/google/gwt/resources/rg/ImageBundleBuilder.java
/releases/2.0/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java /releases/2.0/user/test/com/google/gwt/resources/client/ImageResourceTest.java
 /releases/2.0/user/test/com/google/gwt/resources/client/largeLossy.jpg

=======================================
--- /dev/null   
+++ /releases/2.0/user/test/com/google/gwt/resources/client/complexLossy.jpg Tue Jan 19 07:13:03 2010
Binary file, no diff available.
=======================================
--- /releases/2.0/branch-info.txt       Tue Jan 19 06:59:10 2010
+++ /releases/2.0/branch-info.txt       Tue Jan 19 07:13:03 2010
@@ -1262,3 +1262,8 @@
Allow CssResource to parse identifiers containing underscores or that have a leading hyphen. svn merge -c 7413 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk

+tr...@7424 was merged into this branch
+  Prevent InlineResourceContext from creating too-long data: URLs.
+  Disables composition of lossy source images.
+ svn merge -c 7424 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk
+
=======================================
--- /releases/2.0/user/src/com/google/gwt/resources/client/impl/ImageResourcePrototype.java Thu Jul 30 11:19:40 2009 +++ /releases/2.0/user/src/com/google/gwt/resources/client/impl/ImageResourcePrototype.java Tue Jan 19 07:13:03 2010
@@ -24,6 +24,7 @@
 public class ImageResourcePrototype implements ImageResource {

   private final boolean animated;
+  private final boolean lossy;
   private final String name;
   private final String url;
   private final int left;
@@ -35,7 +36,7 @@
    * Only called by generated code.
    */
   public ImageResourcePrototype(String name, String url, int left, int top,
-      int width, int height, boolean animated) {
+      int width, int height, boolean animated, boolean lossy) {
     this.name = name;
     this.left = left;
     this.top = top;
@@ -43,6 +44,7 @@
     this.width = width;
     this.url = url;
     this.animated = animated;
+    this.lossy = lossy;
   }

   /**
@@ -87,4 +89,8 @@
   public boolean isAnimated() {
     return animated;
   }
-}
+
+  public boolean isLossy() {
+    return lossy;
+  }
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java Wed May 27 06:48:54 2009 +++ /releases/2.0/user/src/com/google/gwt/resources/rebind/context/InlineResourceContext.java Tue Jan 19 07:13:03 2010
@@ -21,6 +21,11 @@
 import com.google.gwt.core.ext.typeinfo.JClassType;

 class InlineResourceContext extends StaticResourceContext {
+  /**
+   * String constants in Java have a maximum limit that we must obey.
+   */
+  public static final int MAX_ENCODED_SIZE = (2 << 15) - 1;
+
   InlineResourceContext(TreeLogger logger, GeneratorContext context,
       JClassType resourceBundleType) {
     super(logger, context, resourceBundleType);
@@ -37,10 +42,19 @@

       String base64Contents = toBase64(data);

-      return "\"data:" + mimeType + ";base64," + base64Contents + "\"";
-    } else {
-      return super.deploy(suggestedFileName, mimeType, data, true);
-    }
+      String encoded = "\"data:" + mimeType + ";base64," + base64Contents
+          + "\"";
+
+      /*
+ * We know that the encoded format will be one byte per character, since
+       * we're using only ASCII characters.
+       */
+      if (encoded.length() < MAX_ENCODED_SIZE) {
+        return encoded;
+      }
+    }
+
+    return super.deploy(suggestedFileName, mimeType, data, true);
   }

   @Override
=======================================
--- /releases/2.0/user/src/com/google/gwt/resources/rg/ImageBundleBuilder.java Wed Oct 28 07:24:14 2009 +++ /releases/2.0/user/src/com/google/gwt/resources/rg/ImageBundleBuilder.java Tue Jan 19 07:13:03 2010
@@ -20,6 +20,8 @@
 import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

+import org.w3c.dom.Node;
+
 import java.awt.Graphics2D;
 import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
@@ -42,6 +44,8 @@

 import javax.imageio.ImageIO;
 import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
 import javax.imageio.stream.MemoryCacheImageInputStream;

 /**
@@ -294,7 +298,7 @@
    */
   static class ImageRect implements HasRect {

-    private boolean hasBeenPositioned;
+    private boolean hasBeenPositioned, lossy;
     private final int height, width;
     private final BufferedImage[] images;
     private int left, top;
@@ -367,6 +371,14 @@
     public boolean isAnimated() {
       return images.length > 1;
     }
+
+    public boolean isLossy() {
+      return lossy;
+    }
+
+    public void setLossy(boolean lossy) {
+      this.lossy = lossy;
+    }

     public void setPosition(int left, int top) {
       hasBeenPositioned = true;
@@ -669,6 +681,8 @@
         "Adding image '" + imageName + "'", null);

     BufferedImage image = null;
+    // Be safe by default and assume that the incoming image is lossy
+    boolean lossy = true;
     // Load the image
     try {
       /*
@@ -689,6 +703,30 @@
         } else if (numImages == 1) {
           try {
             image = reader.read(0);
+            IIOMetadata metadata = reader.getImageMetadata(0);
+            if (metadata != null
+                && metadata.isStandardMetadataFormatSupported()) {
+ // http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/metadata/doc-files/standard_metadata.html + Node data = metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName); + metadata : for (int i = 0, j = data.getChildNodes().getLength(); i < j; i++) {
+                Node child = data.getChildNodes().item(i);
+                if (child.getLocalName().equalsIgnoreCase("compression")) {
+ for (int k = 0, l = child.getChildNodes().getLength(); k < l; k++) {
+                    Node child2 = child.getChildNodes().item(k);
+ if (child2.getLocalName().equalsIgnoreCase("lossless")) { + Node value = child2.getAttributes().getNamedItem("value");
+                      if (value == null) {
+                        // The default is true, according to the DTD
+                        lossy = false;
+                      } else {
+ lossy = !Boolean.parseBoolean(value.getNodeValue());
+                      }
+                      break metadata;
+                    }
+                  }
+                }
+              }
+            }
           } catch (Exception e) {
             // Hope we have another reader that can handle the image
             continue readers;
@@ -739,8 +777,11 @@
     }

     ImageRect toReturn = new ImageRect(imageName, image);
-
- if (toReturn.height > IMAGE_MAX_SIZE || toReturn.width > IMAGE_MAX_SIZE) {
+    toReturn.setLossy(lossy);
+
+    // Don't composite the image if it's lossy or if it is too big
+    if (lossy || toReturn.height > IMAGE_MAX_SIZE
+        || toReturn.width > IMAGE_MAX_SIZE) {
       throw new UnsuitableForStripException(toReturn);
     }

=======================================
--- /releases/2.0/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java Wed Oct 28 07:24:14 2009 +++ /releases/2.0/user/src/com/google/gwt/resources/rg/ImageResourceGenerator.java Tue Jan 19 07:13:03 2010
@@ -140,7 +140,8 @@
           + urlExpressions[1] + " : " + urlExpressions[0] + ",");
     }
sw.println(rect.getLeft() + ", " + rect.getTop() + ", " + rect.getWidth()
-        + ", " + rect.getHeight() + ", " + rect.isAnimated());
+        + ", " + rect.getHeight() + ", " + rect.isAnimated() + ", "
+        + rect.isLossy());

     sw.outdent();
     sw.print(")");
@@ -245,8 +246,8 @@
       URL normalContents;
       rect = e.getImageRect();

-      if (rect.isAnimated()) {
-        // Can't re-encode animated images, so we emit it as-is
+      if (rect.isAnimated() || rect.isLossy()) {
+        // Can't re-encode animated or lossy images, so we emit it as-is
         normalContents = resource;
       } else {
         normalContents = reencodeToTempFile(logger, rect);
=======================================
--- /releases/2.0/user/test/com/google/gwt/resources/client/ImageResourceTest.java Wed Nov 25 10:09:37 2009 +++ /releases/2.0/user/test/com/google/gwt/resources/client/ImageResourceTest.java Tue Jan 19 07:13:03 2010
@@ -23,6 +23,7 @@
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.resources.client.ImageResource.ImageOptions;
 import com.google.gwt.resources.client.ImageResource.RepeatStyle;
+import com.google.gwt.resources.client.impl.ImageResourcePrototype;
 import com.google.gwt.user.client.ui.Image;
 import com.google.gwt.user.client.ui.RootPanel;

@@ -34,6 +35,13 @@
     @Source("animated.gif")
     ImageResource animated();

+    /**
+     * This image shouldn't be re-encoded as a PNG or it will dramatically
+ * increase in size, although it's still small enough to be encoded as a
+     * data URL as-is.
+     */
+    ImageResource complexLossy();
+
     @Source("16x16.png")
     ImageResource i16x16();

@@ -83,6 +91,7 @@
     ImageResource a = r.animated();

     assertTrue(a.isAnimated());
+    assertFalse(((ImageResourcePrototype) a).isLossy());
     assertEquals(16, a.getWidth());
     assertEquals(16, a.getHeight());
     assertEquals(0, a.getLeft());
@@ -137,12 +146,10 @@
     ImageResource lossy = r.largeLossy();
     ImageResource lossless = r.largeLossless();

-    // The large, lossless image should not be bundled
-    if (!i64.getURL().startsWith("data:")) {
-      assertFalse(i64.getURL().equals(lossless.getURL()));
-    }
+    assertFalse(((ImageResourcePrototype) lossless).isLossy());

     // Make sure that the large, lossy image isn't bundled with the rest
+    assertTrue(((ImageResourcePrototype) lossy).isLossy());
     assertTrue(!i64.getURL().equals(lossy.getURL()));

     assertEquals(16, r.i16x16Vertical().getWidth());
=======================================
--- /releases/2.0/user/test/com/google/gwt/resources/client/largeLossy.jpg Wed Mar 11 15:01:48 2009 +++ /releases/2.0/user/test/com/google/gwt/resources/client/largeLossy.jpg Tue Jan 19 07:13:03 2010
Binary file, no diff available.
-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to