Refactored width/height values into superclass and enabled construction of RGBMonochromeBitmapSource from a Bitmap

git-svn-id: https://zxing.googlecode.com/svn/trunk@846 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2009-02-09 21:25:45 +00:00
parent 13c1ec5145
commit f2a9165b7c
6 changed files with 44 additions and 81 deletions

View file

@ -34,8 +34,6 @@ public final class YUVMonochromeBitmapSource extends BaseMonochromeBitmapSource
private final int mDataWidth; private final int mDataWidth;
private final int mCropTop; private final int mCropTop;
private final int mCropLeft; private final int mCropLeft;
private final int mCropBottom;
private final int mCropRight;
/** /**
* Builds an object around a YUV buffer from the camera. The image is not cropped. * Builds an object around a YUV buffer from the camera. The image is not cropped.
@ -80,6 +78,7 @@ public final class YUVMonochromeBitmapSource extends BaseMonochromeBitmapSource
int cropLeft, int cropLeft,
int cropBottom, int cropBottom,
int cropRight) { int cropRight) {
super(cropBottom - cropTop, cropRight - cropLeft);
if (cropRight - cropLeft > dataWidth || cropBottom - cropTop > dataHeight) { if (cropRight - cropLeft > dataWidth || cropBottom - cropTop > dataHeight) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
@ -87,18 +86,6 @@ public final class YUVMonochromeBitmapSource extends BaseMonochromeBitmapSource
mDataWidth = dataWidth; mDataWidth = dataWidth;
this.mCropTop = cropTop; this.mCropTop = cropTop;
this.mCropLeft = cropLeft; this.mCropLeft = cropLeft;
this.mCropBottom = cropBottom;
this.mCropRight = cropRight;
}
@Override
public int getHeight() {
return mCropBottom - mCropTop;
}
@Override
public int getWidth() {
return mCropRight - mCropLeft;
} }
/** /**

View file

@ -24,16 +24,22 @@ import java.io.FileNotFoundException;
public final class RGBMonochromeBitmapSource extends BaseMonochromeBitmapSource { public final class RGBMonochromeBitmapSource extends BaseMonochromeBitmapSource {
private final int mWidth;
private final int mHeight;
private final byte[] mLuminances; private final byte[] mLuminances;
public RGBMonochromeBitmapSource(String path) throws FileNotFoundException { public RGBMonochromeBitmapSource(String path) throws FileNotFoundException {
this(loadBitmap(path));
}
private static Bitmap loadBitmap(String path) throws FileNotFoundException {
Bitmap bitmap = BitmapFactory.decodeFile(path); Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap == null) { if (bitmap == null) {
throw new FileNotFoundException("Couldn't open " + path); throw new FileNotFoundException("Couldn't open " + path);
} }
return bitmap;
}
public RGBMonochromeBitmapSource(Bitmap bitmap) {
super(bitmap.getHeight(), bitmap.getWidth());
int width = bitmap.getWidth(); int width = bitmap.getWidth();
int height = bitmap.getHeight(); int height = bitmap.getHeight();
int[] pixels = new int[width * height]; int[] pixels = new int[width * height];
@ -42,8 +48,6 @@ public final class RGBMonochromeBitmapSource extends BaseMonochromeBitmapSource
// In order to measure pure decoding speed, we convert the entire image to a greyscale array up // In order to measure pure decoding speed, we convert the entire image to a greyscale array up
// front, which is the same as the Y channel of the YUVMonochromeBitmapSource in the real app. // front, which is the same as the Y channel of the YUVMonochromeBitmapSource in the real app.
mLuminances = new byte[width * height]; mLuminances = new byte[width * height];
mWidth = width;
mHeight = height;
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
int offset = y * height; int offset = y * height;
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
@ -62,24 +66,14 @@ public final class RGBMonochromeBitmapSource extends BaseMonochromeBitmapSource
} }
} }
@Override
public int getHeight() {
return mHeight;
}
@Override
public int getWidth() {
return mWidth;
}
@Override @Override
protected int getLuminance(int x, int y) { protected int getLuminance(int x, int y) {
return mLuminances[y * mWidth + x] & 0xff; return mLuminances[y * getWidth() + x] & 0xff;
} }
@Override @Override
protected int[] getLuminanceRow(int y, int[] row) { protected int[] getLuminanceRow(int y, int[] row) {
int width = mWidth; int width = getWidth();
if (row == null || row.length < width) { if (row == null || row.length < width) {
row = new int[width]; row = new int[width];
} }
@ -92,8 +86,8 @@ public final class RGBMonochromeBitmapSource extends BaseMonochromeBitmapSource
@Override @Override
protected int[] getLuminanceColumn(int x, int[] column) { protected int[] getLuminanceColumn(int x, int[] column) {
int width = mWidth; int width = getWidth();
int height = mHeight; int height = getHeight();
if (column == null || column.length < height) { if (column == null || column.length < height) {
column = new int[height]; column = new int[height];
} }

View file

@ -33,13 +33,12 @@ import java.awt.image.PixelGrabber;
*/ */
public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSource { public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSource {
private final int height;
private final int width;
private final int[] pixels; private final int[] pixels;
public AWTImageMonochromeBitmapSource(Image image) throws ReaderException { public AWTImageMonochromeBitmapSource(Image image) throws ReaderException {
height = image.getHeight(null); super(image.getHeight(null), image.getWidth(null));
width = image.getWidth(null); int height = getHeight();
int width = getWidth();
pixels = new int[height * width]; pixels = new int[height * width];
// Seems best in this situation to grab all pixels upfront. Grabbing any individual pixel // Seems best in this situation to grab all pixels upfront. Grabbing any individual pixel
// entails creating a relatively expensive object and calling through several methods. // entails creating a relatively expensive object and calling through several methods.
@ -51,26 +50,19 @@ public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSo
} }
} }
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
/** /**
* See <code>com.google.zxing.client.j2me.LCDUIImageMonochromeBitmapSource</code> for more explanation * See <code>com.google.zxing.client.j2me.LCDUIImageMonochromeBitmapSource</code> for more explanation
* of the computation used in this method. * of the computation used in this method.
*/ */
protected int getLuminance(int x, int y) { protected int getLuminance(int x, int y) {
int pixel = pixels[y * width + x]; int pixel = pixels[y * getWidth() + x];
return (((pixel & 0x00FF0000) >> 16) + return (((pixel & 0x00FF0000) >> 16) +
((pixel & 0x0000FF00) >> 7) + ((pixel & 0x0000FF00) >> 7) +
(pixel & 0x000000FF )) >> 2; (pixel & 0x000000FF )) >> 2;
} }
protected int[] getLuminanceRow(int y, int[] row) { protected int[] getLuminanceRow(int y, int[] row) {
int width = getWidth();
if (row == null || row.length < width) { if (row == null || row.length < width) {
row = new int[width]; row = new int[width];
} }
@ -85,6 +77,8 @@ public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSo
} }
protected int[] getLuminanceColumn(int x, int[] column) { protected int[] getLuminanceColumn(int x, int[] column) {
int height = getHeight();
int width = getWidth();
if (column == null || column.length < height) { if (column == null || column.length < height) {
column = new int[height]; column = new int[height];
} }

View file

@ -28,12 +28,16 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
private final int height;
private final int width;
private int blackPoint; private int blackPoint;
private BlackPointEstimationMethod lastMethod; private BlackPointEstimationMethod lastMethod;
private int lastArgument; private int lastArgument;
private int[] luminances; private int[] luminances;
protected BaseMonochromeBitmapSource() { protected BaseMonochromeBitmapSource(int height, int width) {
this.height = height;
this.width = width;
blackPoint = 0x7F; blackPoint = 0x7F;
lastMethod = null; lastMethod = null;
lastArgument = 0; lastArgument = 0;
@ -151,14 +155,18 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
return false; return false;
} }
// These two methods should not need to exist because they are defined in the interface that public final int getHeight() {
// this abstract class implements. However this seems to cause problems on some Nokias. return height;
}
public final int getWidth() {
return width;
}
// These methods below should not need to exist because they are defined in the interface that
// this abstract class implements. However this seems to cause problems on some Nokias.
// So we write these redundant declarations. // So we write these redundant declarations.
public abstract int getHeight();
public abstract int getWidth();
/** /**
* Retrieves the luminance at the pixel x,y in the bitmap. This method is only used for estimating * Retrieves the luminance at the pixel x,y in the bitmap. This method is only used for estimating
* the black point and implementing getBlackRow() - it is not meant for decoding, hence it is not * the black point and implementing getBlackRow() - it is not meant for decoding, hence it is not

View file

@ -29,28 +29,17 @@ import javax.microedition.lcdui.Image;
public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmapSource { public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmapSource {
private final Image image; private final Image image;
private final int height;
private final int width;
private final int[] pixelHolder; private final int[] pixelHolder;
public LCDUIImageMonochromeBitmapSource(Image image) { public LCDUIImageMonochromeBitmapSource(Image image) {
super(image.getHeight(), image.getWidth());
this.image = image; this.image = image;
height = image.getHeight();
width = image.getWidth();
pixelHolder = new int[1]; pixelHolder = new int[1];
} }
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
// This is expensive and should be used very sparingly. // This is expensive and should be used very sparingly.
protected int getLuminance(int x, int y) { protected int getLuminance(int x, int y) {
image.getRGB(pixelHolder, 0, width, x, y, 1, 1); image.getRGB(pixelHolder, 0, getWidth(), x, y, 1, 1);
int pixel = pixelHolder[0]; int pixel = pixelHolder[0];
// Instead of multiplying by 306, 601, 117, we multiply by 256, 512, 256, so that // Instead of multiplying by 306, 601, 117, we multiply by 256, 512, 256, so that
@ -72,6 +61,7 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
// For efficiency, the RGB data and the luminance data share the same array. // For efficiency, the RGB data and the luminance data share the same array.
protected int[] getLuminanceRow(int y, int[] row) { protected int[] getLuminanceRow(int y, int[] row) {
int width = getWidth();
if (row == null || row.length < width) { if (row == null || row.length < width) {
row = new int[width]; row = new int[width];
} }
@ -86,6 +76,7 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
} }
protected int[] getLuminanceColumn(int x, int[] column) { protected int[] getLuminanceColumn(int x, int[] column) {
int height = getHeight();
if (column == null || column.length < height) { if (column == null || column.length < height) {
column = new int[height]; column = new int[height];
} }

View file

@ -41,8 +41,6 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
private final BufferedImage image; private final BufferedImage image;
private final int left; private final int left;
private final int top; private final int top;
private final int width;
private final int height;
/** /**
* Creates an instance that uses the entire given image as a source of pixels to decode. * Creates an instance that uses the entire given image as a source of pixels to decode.
@ -64,6 +62,7 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
* @param bottom likewise, one more than the y coordinate of the bottommost pixels to decode * @param bottom likewise, one more than the y coordinate of the bottommost pixels to decode
*/ */
public BufferedImageMonochromeBitmapSource(BufferedImage image, int left, int top, int right, int bottom) { public BufferedImageMonochromeBitmapSource(BufferedImage image, int left, int top, int right, int bottom) {
super(bottom - top, right - left);
this.image = image; this.image = image;
int sourceHeight = image.getHeight(); int sourceHeight = image.getHeight();
int sourceWidth = image.getWidth(); int sourceWidth = image.getWidth();
@ -72,8 +71,6 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
} }
this.left = left; this.left = left;
this.top = top; this.top = top;
this.width = right - left;
this.height = bottom - top;
} }
/** /**
@ -84,16 +81,6 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
return image; return image;
} }
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override @Override
public MonochromeBitmapSource rotateCounterClockwise() { public MonochromeBitmapSource rotateCounterClockwise() {
if (!isRotateSupported()) { if (!isRotateSupported()) {
@ -109,8 +96,8 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
op.filter(image, rotatedImage); op.filter(image, rotatedImage);
return new BufferedImageMonochromeBitmapSource(rotatedImage, return new BufferedImageMonochromeBitmapSource(rotatedImage,
top, top,
sourceWidth - (left + width), sourceWidth - (left + getWidth()),
top + height, top + getHeight(),
sourceWidth - left); sourceWidth - left);
} }
@ -140,6 +127,7 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
@Override @Override
protected int[] getLuminanceRow(int y, int[] row) { protected int[] getLuminanceRow(int y, int[] row) {
int width = getWidth();
if (row == null || row.length < width) { if (row == null || row.length < width) {
row = new int[width]; row = new int[width];
} }
@ -155,6 +143,7 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
@Override @Override
protected int[] getLuminanceColumn(int x, int[] column) { protected int[] getLuminanceColumn(int x, int[] column) {
int height = getHeight();
if (column == null || column.length < height) { if (column == null || column.length < height) {
column = new int[height]; column = new int[height];
} }