boofcv.android.ImplConvertBitmap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-android Show documentation
Show all versions of boofcv-android Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2011-2018, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* 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 boofcv.android;
import android.graphics.Bitmap;
import boofcv.struct.image.*;
/**
* Low level implementations of Bitmap conversion routines. Contains functions
* which are not being used for benchmarking purposes.
*
* When converting into 565 format a lookup table is used. The equations used to compute
* the table round instead of flooring to minimize error. I believe that this is what the Android
* library does too, without looking at the code.
*
* @author Peter Abeles
*
*/
public class ImplConvertBitmap {
// storages values used to convert to 565 format
private static int table5[] = new int[ 256 ];
private static int table6[] = new int[ 256 ];
static {
for( int i = 0; i < table5.length; i++ ) {
// minimize error by rounding instead of flooring
table5[i] = (int)Math.round(i*0x1F/255.0);
table6[i] = (int)Math.round(i*0x3F/255.0);
}
}
public static void bitmapToGrayRGB(Bitmap input, GrayU8 output) {
final int h = output.height;
final int w = output.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++) {
int rgb = pixels[indexSrc++];
int value = (((rgb >> 16) & 0xFF) + ((rgb >> 8) & 0xFF) + (rgb & 0xFF)) / 3;
output.data[indexDst++] = (byte) value;
}
}
}
public static void bitmapToGrayRGB(Bitmap input, GrayF32 output) {
final int h = output.height;
final int w = output.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int index = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++) {
int rgb = pixels[indexSrc++];
float value = (((rgb >> 16) & 0xFF) + ((rgb >> 8) & 0xFF) + (rgb & 0xFF)) / 3f;
output.data[index++] = value;
}
}
}
public static void bitmapToPlanarRGB_U8(Bitmap input, Planar output) {
final int h = output.height;
final int w = output.width;
GrayU8 R = output.getBand(0);
GrayU8 G = output.getBand(1);
GrayU8 B = output.getBand(2);
GrayU8 A = output.getBand(3);
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++, indexDst++ ) {
int rgb = pixels[indexSrc++];
A.data[indexDst] = (byte)(rgb >> 24);
R.data[indexDst] = (byte)((rgb >> 16) & 0xFF);
G.data[indexDst] = (byte)((rgb >> 8) & 0xFF);
B.data[indexDst] = (byte)(rgb & 0xFF);
}
}
}
public static void bitmapToInterleaved(Bitmap input, InterleavedU8 output) {
final int h = output.height;
final int w = output.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++) {
int rgb = pixels[indexSrc++];
output.data[indexDst++] = (byte)(rgb >> 24);
output.data[indexDst++] = (byte)((rgb >> 16) & 0xFF);
output.data[indexDst++] = (byte)((rgb >> 8) & 0xFF);
output.data[indexDst++] = (byte)(rgb & 0xFF);
}
}
}
public static void bitmapToPlanarRGB_F32(Bitmap input, Planar output) {
final int h = output.height;
final int w = output.width;
GrayF32 R = output.getBand(0);
GrayF32 G = output.getBand(1);
GrayF32 B = output.getBand(2);
GrayF32 A = output.getBand(3);
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++, indexDst++ ) {
int rgb = pixels[indexSrc++];
A.data[indexDst] = (rgb >> 24) & 0xFF;
R.data[indexDst] = (rgb >> 16) & 0xFF;
G.data[indexDst] = (rgb >> 8) & 0xFF;
B.data[indexDst] = rgb & 0xFF;
}
}
}
public static void bitmapToInterleaved(Bitmap input, InterleavedF32 output) {
final int h = output.height;
final int w = output.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int indexSrc = 0;
input.getPixels(pixels, 0, w, 0, y, w, 1);
for (int x = 0; x < w; x++ ) {
int rgb = pixels[indexSrc++];
output.data[indexDst++] = (rgb >> 24) & 0xFF;
output.data[indexDst++] = (rgb >> 16) & 0xFF;
output.data[indexDst++] = (rgb >> 8) & 0xFF;
output.data[indexDst++] = rgb & 0xFF;
}
}
}
public static void grayToBitmapRGB(GrayU8 input, Bitmap output) {
final int h = input.height;
final int w = input.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
int indexDst = 0;
for (int x = 0; x < w; x++) {
int gray = input.data[indexSrc++] & 0xFF;
pixels[indexDst++] = (0xFF << 24) | (gray << 16) | (gray << 8) | gray;
}
output.setPixels(pixels,0,w,0,y,w,1);
}
}
public static void grayToBitmapRGB(GrayF32 input, Bitmap output) {
final int h = input.height;
final int w = input.width;
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
int indexDst = 0;
for (int x = 0; x < w; x++) {
int gray = (int)input.data[indexSrc++];
pixels[indexDst++] = (0xFF << 24) | (gray << 16) | (gray << 8) | gray;
}
output.setPixels(pixels,0,w,0,y,w,1);
}
}
public static void planarToBitmapRGB_U8(Planar input, Bitmap output) {
final int h = input.height;
final int w = input.width;
GrayU8 R = input.getBand(0);
GrayU8 G = input.getBand(1);
GrayU8 B = input.getBand(2);
GrayU8 A = input.getBand(3);
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
int indexDst = 0;
for (int x = 0; x < w; x++,indexSrc++) {
pixels[indexDst++] = (A.data[indexSrc] & 0xFF) << 24 | (R.data[indexSrc] & 0xFF) << 16 | (G.data[indexSrc] & 0xFF) << 8 | (B.data[indexSrc] & 0xFF);
}
output.setPixels(pixels,0,w,0,y,w,1);
}
}
public static void planarToBitmapRGB_F32(Planar input, Bitmap output) {
final int h = input.height;
final int w = input.width;
GrayF32 R = input.getBand(0);
GrayF32 G = input.getBand(1);
GrayF32 B = input.getBand(2);
GrayF32 A = input.getBand(3);
// read one row at a time instead of the entire image to reduce memory requirements
int[] pixels = new int[w];
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
int indexDst = 0;
for (int x = 0; x < w; x++,indexSrc++) {
int r = (int)R.data[indexSrc];
int g = (int)G.data[indexSrc];
int b = (int)B.data[indexSrc];
int a = (int)A.data[indexSrc];
pixels[indexDst++] = a << 24 | r << 16 | g << 8 | b;
}
output.setPixels(pixels,0,w,0,y,w,1);
}
}
public static void arrayToGray( int input[], Bitmap.Config config, GrayU8 output ) {
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
int value = (((rgb >> 16) & 0xFF) + ((rgb >> 8) & 0xFF) + (rgb & 0xFF)) / 3;
output.data[indexDst++] = (byte) value;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToGray(int input[], Bitmap.Config config, GrayF32 output )
{
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
int value = (((rgb >> 16) & 0xFF) + ((rgb >> 8) & 0xFF) + (rgb & 0xFF)) / 3;
output.data[indexDst++] = value;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToPlanar_U8(int input[], Bitmap.Config config , Planar output ) {
final int h = output.height;
final int w = output.width;
GrayU8 R = output.getBand(0);
GrayU8 G = output.getBand(1);
GrayU8 B = output.getBand(2);
GrayU8 A = output.getBand(3);
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
A.data[indexDst] = (byte)(rgb >> 24);
B.data[indexDst] = (byte)(rgb >> 16);
G.data[indexDst] = (byte)(rgb >> 8);
R.data[indexDst] = (byte)rgb;
indexDst++;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToInterleaved(int input[], Bitmap.Config config , InterleavedU8 output ) {
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w*output.numBands;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
output.data[indexDst++] = (byte)(rgb >> 24);
output.data[indexDst++] = (byte)(rgb >> 16);
output.data[indexDst++] = (byte)(rgb >> 8);
output.data[indexDst++] = (byte)rgb;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToPlanar_F32(int input[], Bitmap.Config config , Planar output ) {
final int h = output.height;
final int w = output.width;
GrayF32 R = output.getBand(0);
GrayF32 G = output.getBand(1);
GrayF32 B = output.getBand(2);
GrayF32 A = output.getBand(3);
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
A.data[indexDst] = (rgb >> 24) & 0xFF;
B.data[indexDst] = (rgb >> 16) & 0xFF;
G.data[indexDst] = (rgb >> 8) & 0xFF;
R.data[indexDst] = rgb & 0xFF;
indexDst++;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToInterleaved(int input[], Bitmap.Config config , InterleavedF32 output ) {
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w*output.numBands;
// for (int x = 0; x < w; x++) {
while (indexDst < end) {
int rgb = input[indexSrc++];
output.data[indexDst++] = (rgb >> 24) & 0xFF;
output.data[indexDst++] = (rgb >> 16) & 0xFF;
output.data[indexDst++] = (rgb >> 8) & 0xFF;
output.data[indexDst++] = rgb & 0xFF;
}
}
break;
default:
throw new RuntimeException("Image type not yet supported: "+config);
}
}
public static void arrayToGray(byte array[], Bitmap.Config config , GrayU8 output) {
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888: {
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
int value = ((array[indexSrc++] & 0xFF)
+ (array[indexSrc++] & 0xFF) + (array[indexSrc++] & 0xFF)) / 3;
output.data[indexDst++] = (byte) value;
indexSrc++;// skip over alpha channel
}
}
}
break;
case RGB_565:{
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
for (int x = 0; x < w; x++) {
int value = (array[indexSrc++] & 0xFF)
| ((array[indexSrc++] & 0xFF) << 8 );
int r = (value >> 11)*256/32;
int g = ((value & 0x07E0) >> 5)*256/64;
int b = (value & 0x001F)*256/32;
output.data[indexDst++] = (byte) ((r + g + b) / 3);
}
}}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void arrayToGray(byte array[], Bitmap.Config config , GrayF32 output) {
final int h = output.height;
final int w = output.width;
int indexSrc = 0;
switch (config) {
case ARGB_8888: {
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
float value = ((array[indexSrc++] & 0xFF) + (array[indexSrc++] & 0xFF) + (array[indexSrc++] & 0xFF)) / 3f;
output.data[indexDst++] = value;
indexSrc++;// skip over alpha channel
}
}
}
break;
case RGB_565:{
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
for (int x = 0; x < w; x++) {
int value = (array[indexSrc++] & 0xFF)
| ((array[indexSrc++] & 0xFF) << 8 );
int r = (value >> 11)*256/32;
int g = ((value & 0x07E0) >> 5)*256/64;
int b = (value & 0x001F)*256/32;
output.data[indexDst++] = (r + g + b) / 3;
}
}}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void arrayToPlanar_U8(byte []input, Bitmap.Config config, Planar output) {
final int h = output.height;
final int w = output.width;
GrayU8 R = output.getBand(0);
GrayU8 G = output.getBand(1);
GrayU8 B = output.getBand(2);
int indexSrc = 0;
switch (config) {
case ARGB_8888: {
if( output.getNumBands() == 4 ) {
GrayU8 A = output.getBand(3);
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
R.data[indexDst] = input[indexSrc++];
G.data[indexDst] = input[indexSrc++];
B.data[indexDst] = input[indexSrc++];
A.data[indexDst] = input[indexSrc++];
indexDst++;
}
}
} else if( output.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
R.data[indexDst] = input[indexSrc++];
G.data[indexDst] = input[indexSrc++];
B.data[indexDst] = input[indexSrc++];
indexSrc++;
indexDst++;
}
}
} else {
throw new IllegalArgumentException("Expected 3 or 4 bands in output");
}
}
break;
case RGB_565:{
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
for (int x = 0; x < w; x++,indexDst++) {
int value = (input[indexSrc++] & 0xFF)
| ((input[indexSrc++] & 0xFF) << 8 );
int r = (value >> 11)*0xFF/0x1F;
int g = ((value >> 5) & 0x3F )*0xFF/0x3F;
int b = (value & 0x1F)*0xFF/0x1F;
B.data[indexDst] = (byte)b;
G.data[indexDst] = (byte)g;
R.data[indexDst] = (byte)r;
}
}}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void arrayToPlanar_F32(byte []input, Bitmap.Config config, Planar output) {
final int h = output.height;
final int w = output.width;
GrayF32 R = output.getBand(0);
GrayF32 G = output.getBand(1);
GrayF32 B = output.getBand(2);
int indexSrc = 0;
switch (config) {
case ARGB_8888: {
if( output.getNumBands() == 4 ) {
GrayF32 A = output.getBand(3);
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
R.data[indexDst] = input[indexSrc++] & 0xFF;
G.data[indexDst] = input[indexSrc++] & 0xFF;
B.data[indexDst] = input[indexSrc++] & 0xFF;
A.data[indexDst] = input[indexSrc++] & 0xFF;
indexDst++;
}
}
} else if( output.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
int end = indexDst + w;
// for (int x = 0; x < w; x++, indexSrc++) {
while (indexDst < end) {
R.data[indexDst] = input[indexSrc++] & 0xFF;
G.data[indexDst] = input[indexSrc++] & 0xFF;
B.data[indexDst] = input[indexSrc++] & 0xFF;
indexSrc++;
indexDst++;
}
}
} else {
throw new IllegalArgumentException("Expected 3 or 4 bands in output");
}
}
break;
case RGB_565:{
for (int y = 0; y < h; y++) {
int indexDst = output.startIndex + y * output.stride;
for (int x = 0; x < w; x++,indexDst++) {
int value = (input[indexSrc++] & 0xFF)
| ((input[indexSrc++] & 0xFF) << 8 );
int r = (value >> 11)*0xFF/0x1F;
int g = ((value >> 5) & 0x3F )*0xFF/0x3F;
int b = (value & 0x1F)*0xFF/0x1F;
B.data[indexDst] = b & 0xFF;
G.data[indexDst] = g & 0xFF;
R.data[indexDst] = r & 0xFF;
}
}}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void grayToArray(GrayU8 input, byte []output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
int indexDst = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int value = input.data[indexSrc++] & 0xFF;
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) 0xFF;
}
}
break;
case RGB_565:
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int value = input.data[indexSrc++] & 0xFF;
int value5 = table5[value];
int value6 = table6[value];
int rgb565 = (value5 << 11) | (value6 << 5) | value5;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void grayToArray(GrayF32 input, byte[] output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
int indexDst = 0;
switch (config) {
case ARGB_8888:
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int value = (int)input.data[indexSrc++];
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) value;
output[indexDst++] = (byte) 0xFF;
}
}
break;
case RGB_565:
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int value = (int)input.data[indexSrc++];
int value5 = table5[value];
int value6 = table6[value];
int rgb565 = (value5 << 11) | (value6 << 5) | value5;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void planarToArray_U8(Planar input, byte[] output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
GrayU8 R = input.getBand(0);
GrayU8 G = input.getBand(1);
GrayU8 B = input.getBand(2);
int indexDst = 0;
switch (config) {
case ARGB_8888:
if( input.getNumBands() == 4 ) {
GrayU8 A = input.getBand(3);
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++,indexSrc++) {
output[indexDst++] = R.data[indexSrc];
output[indexDst++] = G.data[indexSrc];
output[indexDst++] = B.data[indexSrc];
output[indexDst++] = A.data[indexSrc];
}
}
} else if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++,indexSrc++) {
output[indexDst++] = R.data[indexSrc];
output[indexDst++] = G.data[indexSrc];
output[indexDst++] = B.data[indexSrc];
output[indexDst++] = (byte)0xFF;
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 or 4 bands");
}
break;
case RGB_565:
if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++, indexSrc++) {
int r = R.data[indexSrc] & 0xFF;
int g = G.data[indexSrc] & 0xFF;
int b = B.data[indexSrc] & 0xFF;
int valueR = table5[r];
int valueG = table6[g];
int valueB = table5[b];
int rgb565 = (valueR << 11) | (valueG << 5) | valueB;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 bands");
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void planarToArray_F32(Planar input, byte[] output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
GrayF32 R = input.getBand(0);
GrayF32 G = input.getBand(1);
GrayF32 B = input.getBand(2);
int indexDst = 0;
switch (config) {
case ARGB_8888:
if( input.getNumBands() == 4 ) {
GrayF32 A = input.getBand(3);
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++,indexSrc++) {
output[indexDst++] = (byte)R.data[indexSrc];
output[indexDst++] = (byte)G.data[indexSrc];
output[indexDst++] = (byte)B.data[indexSrc];
output[indexDst++] = (byte)A.data[indexSrc];
}
}
} else if( input.getNumBands() == 3 ){
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++,indexSrc++) {
output[indexDst++] = (byte)R.data[indexSrc];
output[indexDst++] = (byte)G.data[indexSrc];
output[indexDst++] = (byte)B.data[indexSrc];
output[indexDst++] = (byte)255;
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 or 4 bands");
}
break;
case RGB_565:
if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++, indexSrc++) {
int r = (int) R.data[indexSrc];
int g = (int) G.data[indexSrc];
int b = (int) B.data[indexSrc];
int valueR = table5[r];
int valueG = table6[g];
int valueB = table5[b];
int rgb565 = (valueR << 11) | (valueG << 5) | valueB;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 bands");
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void interleavedToArray(InterleavedU8 input, byte[] output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
int indexDst = 0;
switch (config) {
case ARGB_8888:
if( input.getNumBands() == 4 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = input.data[indexSrc++];
}
}
} else if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = input.data[indexSrc++];
output[indexDst++] = (byte)0xFF;
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 or 4 bands");
}
break;
case RGB_565:
if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int r = input.data[indexSrc++] & 0xFF;
int g = input.data[indexSrc++] & 0xFF;
int b = input.data[indexSrc++] & 0xFF;
int valueR = table5[r];
int valueG = table6[g];
int valueB = table5[b];
int rgb565 = (valueR << 11) | (valueG << 5) | valueB;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 bands");
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void interleavedToArray(InterleavedF32 input, byte[] output , Bitmap.Config config ) {
final int h = input.height;
final int w = input.width;
int indexDst = 0;
switch (config) {
case ARGB_8888:
if( input.getNumBands() == 4 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)input.data[indexSrc++];
}
}
} else if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)input.data[indexSrc++];
output[indexDst++] = (byte)0xFF;
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 or 4 bands");
}
break;
case RGB_565:
if( input.getNumBands() == 3 ) {
for (int y = 0; y < h; y++) {
int indexSrc = input.startIndex + y * input.stride;
for (int x = 0; x < w; x++) {
int r = (int)input.data[indexSrc++];
int g = (int)input.data[indexSrc++];
int b = (int)input.data[indexSrc++];
int valueR = table5[r];
int valueG = table6[g];
int valueB = table5[b];
int rgb565 = (valueR << 11) | (valueG << 5) | valueB;
output[indexDst++] = (byte) rgb565;
output[indexDst++] = (byte) (rgb565 >> 8);
}
}
} else {
throw new IllegalArgumentException("Expected input to have 3 bands");
}
break;
case ALPHA_8:
throw new RuntimeException("ALPHA_8 seems to have some weired internal format and is not currently supported");
case ARGB_4444:
throw new RuntimeException("Isn't 4444 deprecated?");
}
}
public static void interleavedYuvToArgb8888(InterleavedU8 input, byte[] output)
{
final int width = input.width;
final int height = input.height;
int indexDst = 0;
for( int row = 0; row < height; row++ ) {
int indexSrc = input.startIndex + input.stride*row;
for( int col = 0; col < width; col++ ) {
int y = 1191*((input.data[indexSrc++] & 0xFF) - 16);
int cr = (input.data[ indexSrc++ ] & 0xFF) - 128;
int cb = (input.data[ indexSrc++] & 0xFF) - 128;
// if( y < 0 ) y = 0;
y = ((y >>> 31)^1)*y;
int r = (y + 1836*cr) >> 10;
int g = (y - 547*cr - 218*cb) >> 10;
int b = (y + 2165*cb) >> 10;
// if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
// if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
// if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
r *= ((r >>> 31)^1);
g *= ((g >>> 31)^1);
b *= ((b >>> 31)^1);
// The bitwise code below isn't faster than than the if statement below
// r |= (((255-r) >>> 31)*0xFF);
// g |= (((255-g) >>> 31)*0xFF);
// b |= (((255-b) >>> 31)*0xFF);
if( r > 255 ) r = 255;
if( g > 255 ) g = 255;
if( b > 255 ) b = 255;
output[indexDst++] = (byte)r;
output[indexDst++] = (byte)g;
output[indexDst++] = (byte)b;
output[indexDst++] = (byte)0xFF;
}
}
}
public static void interleavedYuvToRGB565(InterleavedU8 input, byte[] output)
{
final int width = input.width;
final int height = input.height;
int indexDst = 0;
for( int row = 0; row < height; row++ ) {
int indexSrc = input.startIndex + input.stride*row;
for( int col = 0; col < width; col++ ) {
int y = 1191*((input.data[indexSrc++] & 0xFF) - 16);
int cr = (input.data[ indexSrc++ ] & 0xFF) - 128;
int cb = (input.data[ indexSrc++] & 0xFF) - 128;
// if( y < 0 ) y = 0;
y = ((y >>> 31)^1)*y;
int r = (y + 1836*cr) >> 10;
int g = (y - 547*cr - 218*cb) >> 10;
int b = (y + 2165*cb) >> 10;
// if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
// if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
// if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
r *= ((r >>> 31)^1);
g *= ((g >>> 31)^1);
b *= ((b >>> 31)^1);
// The bitwise code below isn't faster than than the if statement below
// r |= (((255-r) >>> 31)*0xFF);
// g |= (((255-g) >>> 31)*0xFF);
// b |= (((255-b) >>> 31)*0xFF);
if( r > 255 ) r = 255;
if( g > 255 ) g = 255;
if( b > 255 ) b = 255;
output[indexDst++] = (byte)table5[r];
output[indexDst++] = (byte)table6[g];
output[indexDst++] = (byte)table5[b];
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy