More fixes for java viewer performance regression
diff --git a/java/com/tigervnc/rfb/JpegDecompressor.java b/java/com/tigervnc/rfb/JpegDecompressor.java
index c263736..3154294 100644
--- a/java/com/tigervnc/rfb/JpegDecompressor.java
+++ b/java/com/tigervnc/rfb/JpegDecompressor.java
@@ -29,7 +29,7 @@
   public JpegDecompressor() {}
 
   public void decompress(ByteBuffer jpegBuf, int jpegBufLen,
-    WritableRaster buf, Rect r, PixelFormat pf)
+    PixelBuffer pb, Rect r, PixelFormat pf)
   {
 
     byte[] src = new byte[jpegBufLen];
@@ -39,10 +39,9 @@
       ImageIO.setUseCache(false);
       BufferedImage jpeg =
         ImageIO.read(new MemoryCacheImageInputStream(new ByteArrayInputStream(src)));
-      ColorModel cm = pf.getColorModel();
-      BufferedImage image = new BufferedImage(cm, buf, true, null);
+      BufferedImage image = (BufferedImage)pb.getImage();
       Graphics2D g2 = image.createGraphics();
-      g2.drawImage(jpeg, 0, 0, null);
+      g2.drawImage(jpeg, r.tl.x, r.tl.y, r.width(), r.height(), null);
       g2.dispose();
       image.flush();
       jpeg.flush();
diff --git a/java/com/tigervnc/rfb/PixelBuffer.java b/java/com/tigervnc/rfb/PixelBuffer.java
index 1b7d2c1..18d84d5 100644
--- a/java/com/tigervnc/rfb/PixelBuffer.java
+++ b/java/com/tigervnc/rfb/PixelBuffer.java
@@ -21,6 +21,7 @@
 
 package com.tigervnc.rfb;
 
+import java.awt.*;
 import java.awt.image.*;
 import java.awt.Color;
 import java.nio.*;
@@ -69,6 +70,7 @@
   //   specific format.
   //void getImage(const PixelFormat& pf, void* imageBuf,
   //                const Rect& r, int stride=0) const;
+  public Image getImage() { return image; }
 
   ///////////////////////////////////////////////
   // Framebuffer update methods
@@ -81,4 +83,5 @@
 
   protected PixelFormat format;
   protected int width_, height_;
+  protected Image image;
 }
diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java
index aa468eb..b180707 100644
--- a/java/com/tigervnc/rfb/TightDecoder.java
+++ b/java/com/tigervnc/rfb/TightDecoder.java
@@ -236,8 +236,7 @@
       buflen -= 4;
 
       // We always use direct decoding with JPEG images
-      buf = pb.getBufferRW(r);
-      jd.decompress(bufptr, len, buf, r, pb.getPF());
+      jd.decompress(bufptr, len, pb, r, pb.getPF());
       pb.commitBufferRW(r);
       return;
     }
diff --git a/java/com/tigervnc/vncviewer/JavaPixelBuffer.java b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
index b639673..89c42fe 100644
--- a/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
+++ b/java/com/tigervnc/vncviewer/JavaPixelBuffer.java
@@ -21,7 +21,7 @@
 
 import java.awt.*;
 import java.awt.image.*;
-import java.nio.ByteOrder;
+import java.nio.*;
 
 import com.tigervnc.rfb.*;
 
@@ -31,6 +31,22 @@
   public JavaPixelBuffer(int w, int h) {
     super(getPreferredPF(), w, h,
           getPreferredPF().getColorModel().createCompatibleWritableRaster(w,h));
+    image = new BufferedImage(getPreferredPF().getColorModel(),
+                              getBufferRW(new Rect(0, 0, w, h)), true, null);
+  }
+
+  public synchronized void fillRect(Rect r, byte[] pix)
+  {
+    ColorModel cm = format.getColorModel();
+    int pixel =
+      ByteBuffer.wrap(pix).order(format.getByteOrder()).asIntBuffer().get(0);
+    Color c = new Color(cm.getRGB(pixel));
+    Graphics2D g2 = ((BufferedImage)image).createGraphics();
+    g2.setColor(c);
+    g2.fillRect(r.tl.x, r.tl.y, r.width(), r.height());
+    g2.dispose();
+
+    commitBufferRW(r);
   }
 
   private static PixelFormat getPreferredPF()
diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java
index f7448bc..fd1e6cf 100644
--- a/java/com/tigervnc/vncviewer/Viewport.java
+++ b/java/com/tigervnc/vncviewer/Viewport.java
@@ -101,8 +101,7 @@
     Rect r = frameBuffer.getDamage();
     if (!r.is_empty()) {
       if (image == null)
-        image = (BufferedImage)createImage(frameBuffer.width(), frameBuffer.height());
-      image.getRaster().setDataElements(r.tl.x, r.tl.y, frameBuffer.getBuffer(r));
+        image = (BufferedImage)frameBuffer.getImage();
       if (cc.cp.width != scaledWidth ||
           cc.cp.height != scaledHeight) {
         AffineTransform t = new AffineTransform(); 
@@ -198,7 +197,7 @@
       frameBuffer = createFramebuffer(frameBuffer.getPF(), w, h);
       assert(frameBuffer != null);
       cc.setFramebuffer(frameBuffer);
-      image = null;
+      image = (BufferedImage)frameBuffer.getImage();
     }
     setScaledSize(w, h);
   }