Workaround (I think) for bizarre array corruption problem on Sun WTK and some SE...
[zxing.git] / javame / src / com / google / zxing / client / j2me / LCDUIImageMonochromeBitmapSource.java
index df462de..04d0ca3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2007 ZXing authors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,21 +21,27 @@ import com.google.zxing.common.BaseMonochromeBitmapSource;
 import javax.microedition.lcdui.Image;
 
 /**
- * <p>An implementation based on Java ME's {@link java.awt.Image} representation.</p>
+ * <p>An implementation based on Java ME's {@link Image} representation.</p>
  *
  * @author Sean Owen (srowen@google.com), Daniel Switkin (dswitkin@google.com)
  */
 public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmapSource {
 
-  private final int[] rgbPixels;
-  private final int width;
+  private final Image image;
   private final int height;
+  private final int width;
+  // For why this isn't final, see below
+  private int[] rgbRow;
+  private final int[] pixelHolder;
+  private int cachedRow;
 
   public LCDUIImageMonochromeBitmapSource(Image image) {
-    width = image.getWidth();
+    this.image = image;
     height = image.getHeight();
-    rgbPixels = new int[width * height];
-    image.getRGB(rgbPixels, 0, width, 0, 0, width, height);
+    width = image.getWidth();
+    rgbRow = new int[width];
+    pixelHolder = new int[1];
+    cachedRow = -1;
   }
 
   public int getHeight() {
@@ -47,7 +53,18 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
   }
 
   public int getLuminance(int x, int y) {
-    int pixel = rgbPixels[y * width + x];
+
+    // Below, why the check for rgbRow being the right size? it should never change size
+    // or need to be reallocated. But bizarrely we have seen a but on Sun's WTK, and on
+    // some phones, where the array becomes zero-sized somehow. So we keep making sure the
+    // array is OK.
+    int pixel;
+    if (cachedRow == y && rgbRow.length == width) {
+      pixel = rgbRow[x];
+    } else {
+      image.getRGB(pixelHolder, 0, width, x, y, 1, 1);
+      pixel = pixelHolder[0];
+    }
 
     // Instead of multiplying by 306, 601, 117, we multiply by 256, 512, 256, so that
     // the multiplies can be implemented as shifts.
@@ -66,9 +83,15 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
              (pixel & 0x000000FF       )) >> 2;
   }
 
-  // Nothing to do, since we have direct access to the image data.
   public void cacheRowForLuminance(int y) {
-
+    if (y != cachedRow) {
+      // See explanation above
+      if (rgbRow.length != width) {
+        rgbRow = new int[width];
+      }
+      image.getRGB(rgbRow, 0, width, 0, y, width, 1);
+      cachedRow = y;
+    }
   }
 
 }
\ No newline at end of file