mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Technically split out YUV 4:2:0 and 4:2:2 support and tried implementing RGB conversion for 4:2:0
git-svn-id: https://zxing.googlecode.com/svn/trunk@1119 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
f75a6ec766
commit
87b6b0ec66
|
@ -16,8 +16,6 @@
|
|||
|
||||
package com.google.zxing.client.android;
|
||||
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
/**
|
||||
|
@ -26,18 +24,21 @@ import android.graphics.Bitmap;
|
|||
* superfluous pixels around the perimeter and speed up decoding.
|
||||
*
|
||||
* It works for any pixel format where the Y channel is planar and appears first, including
|
||||
* YCbCr_420_SP and YCbCr_422_SP. Any subsequent color data will be ignored.
|
||||
* YCbCr_420_SP and YCbCr_422_SP.
|
||||
*
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
||||
public abstract class AbstractPlanarYUVLuminanceSource extends BaseLuminanceSource {
|
||||
|
||||
protected static final int OPAQUE_ALPHA = 0xFF000000;
|
||||
|
||||
private final byte[] yuvData;
|
||||
private final int dataWidth;
|
||||
private final int dataHeight;
|
||||
private final int left;
|
||||
private final int top;
|
||||
|
||||
public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top,
|
||||
AbstractPlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top,
|
||||
int width, int height) {
|
||||
super(width, height);
|
||||
|
||||
|
@ -53,7 +54,7 @@ public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public byte[] getRow(int y, byte[] row) {
|
||||
public final byte[] getRow(int y, byte[] row) {
|
||||
if (y < 0 || y >= getHeight()) {
|
||||
throw new IllegalArgumentException("Requested row is outside the image: " + y);
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public byte[] getMatrix() {
|
||||
public final byte[] getMatrix() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
|
@ -98,27 +99,34 @@ public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isCropSupported() {
|
||||
public final boolean isCropSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuminanceSource crop(int left, int top, int width, int height) {
|
||||
return new PlanarYUVLuminanceSource(yuvData, dataWidth, dataHeight, left, top, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataWidth() {
|
||||
public final int getDataWidth() {
|
||||
return dataWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataHeight() {
|
||||
public final int getDataHeight() {
|
||||
return dataHeight;
|
||||
}
|
||||
|
||||
protected final byte[] getYUVData() {
|
||||
return yuvData;
|
||||
}
|
||||
|
||||
protected final int getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
protected final int getTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap renderCroppedGreyscaleBitmap() {
|
||||
public final Bitmap renderCroppedGreyscaleBitmap() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int[] pixels = new int[width * height];
|
||||
|
@ -129,7 +137,7 @@ public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
|||
int outputOffset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
int grey = yuv[inputOffset + x] & 0xff;
|
||||
pixels[outputOffset + x] = (0xff000000) | (grey * 0x00010101);
|
||||
pixels[outputOffset + x] = OPAQUE_ALPHA | (grey * 0x00010101);
|
||||
}
|
||||
inputOffset += dataWidth;
|
||||
}
|
||||
|
@ -139,9 +147,4 @@ public final class PlanarYUVLuminanceSource extends BaseLuminanceSource {
|
|||
return bitmap;
|
||||
}
|
||||
|
||||
// Can't be implemented here, as the color representations vary.
|
||||
@Override
|
||||
public Bitmap renderFullColorBitmap(boolean halfSize) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
|
@ -285,8 +285,10 @@ final class CameraManager {
|
|||
Rect rect = getFramingRect();
|
||||
switch (previewFormat) {
|
||||
case PixelFormat.YCbCr_420_SP:
|
||||
return new PlanarYUV420LuminanceSource(data, width, height, rect.left, rect.top,
|
||||
rect.width(), rect.height());
|
||||
case PixelFormat.YCbCr_422_SP:
|
||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
||||
return new PlanarYUV422LuminanceSource(data, width, height, rect.left, rect.top,
|
||||
rect.width(), rect.height());
|
||||
default:
|
||||
// Handle some non-standard values:
|
||||
|
@ -296,12 +298,12 @@ final class CameraManager {
|
|||
rect.width(), rect.height());
|
||||
} else if (previewFormatString.equals("yuv420p")) {
|
||||
// Assume this is a synonym for YUV420SP -- note the lack of 's'
|
||||
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
|
||||
return new PlanarYUV420LuminanceSource(data, width, height, rect.left, rect.top,
|
||||
rect.width(), rect.height());
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported picture format: " +
|
||||
previewFormat + '/' + previewFormatString);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported picture format: " +
|
||||
previewFormat + '/' + previewFormatString);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -171,7 +171,7 @@ public final class InterleavedYUV422LuminanceSource extends BaseLuminanceSource
|
|||
/**
|
||||
* @link http://en.wikipedia.org/wiki/YUV#Y.27UV444
|
||||
*/
|
||||
private static int yuvToRGB(int y, int u, int v) {
|
||||
static int yuvToRGB(int y, int u, int v) {
|
||||
int c = y - 16;
|
||||
int d = u - 128;
|
||||
int e = v - 128;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.android;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
public final class PlanarYUV420LuminanceSource extends AbstractPlanarYUVLuminanceSource {
|
||||
|
||||
public PlanarYUV420LuminanceSource(byte[] yuvData, int dataWidth, int dataHeight,
|
||||
int left, int top, int width, int height) {
|
||||
super(yuvData, dataWidth, dataHeight, left, top, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuminanceSource crop(int left, int top, int width, int height) {
|
||||
return new PlanarYUV420LuminanceSource(
|
||||
getYUVData(), getDataWidth(), getDataHeight(), left, top, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap renderFullColorBitmap(boolean halfSize) {
|
||||
// TODO implement halfSize
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int dataWidth = getDataWidth();
|
||||
byte[] yuv = getYUVData();
|
||||
int expectedYBytes = width * height;
|
||||
int expectedUBytes = expectedYBytes >> 2;
|
||||
int expectedVBytes = expectedYBytes >> 2;
|
||||
int expectedBytes = expectedYBytes + expectedUBytes + expectedVBytes;
|
||||
if (yuv.length != expectedBytes) {
|
||||
throw new IllegalStateException("Expected " + expectedBytes + " bytes");
|
||||
}
|
||||
|
||||
int[] pixels = new int[width * height];
|
||||
int inputYOffset = getTop() * getDataWidth() + getLeft();
|
||||
int uOffset = expectedYBytes;
|
||||
int vOffset = expectedYBytes + expectedUBytes;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
int outputOffset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
int yOffset = inputYOffset + x;
|
||||
int yDataRow = yOffset / dataWidth;
|
||||
int yDataOffset = yOffset % dataWidth;
|
||||
int uvOffset = ((yDataRow >> 1) * dataWidth + yDataOffset) >> 1;
|
||||
int y1 = yuv[yOffset] & 0xFF;
|
||||
int u = yuv[uOffset + uvOffset] & 0xFF;
|
||||
int v = yuv[vOffset + uvOffset] & 0XFF;
|
||||
pixels[outputOffset + x] =
|
||||
OPAQUE_ALPHA | InterleavedYUV422LuminanceSource.yuvToRGB(y1, u, v);
|
||||
}
|
||||
inputYOffset += dataWidth;
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.zxing.client.android;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
|
||||
public final class PlanarYUV422LuminanceSource extends AbstractPlanarYUVLuminanceSource {
|
||||
|
||||
public PlanarYUV422LuminanceSource(byte[] yuvData, int dataWidth, int dataHeight,
|
||||
int left, int top, int width, int height) {
|
||||
super(yuvData, dataWidth, dataHeight, left, top, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuminanceSource crop(int left, int top, int width, int height) {
|
||||
return new PlanarYUV422LuminanceSource(
|
||||
getYUVData(), getDataWidth(), getDataHeight(), left, top, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap renderFullColorBitmap(boolean halfSize) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue