package org.andengine.opengl.util;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import org.andengine.opengl.texture.PixelFormat;
import android.graphics.Bitmap;
/**
* (c) 2010 Nicolas Gramlich
* (c) 2011 Zynga Inc.
*
* @author Nicolas Gramlich
* @since 18:00:43 - 08.03.2010
*/
public class GLHelper {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
/**
* TODO These conversions could be done in native code!
*/
public static Buffer getPixels(final Bitmap pBitmap, final PixelFormat pPixelFormat) {
return GLHelper.getPixels(pBitmap, pPixelFormat, ByteOrder.nativeOrder());
}
public static Buffer getPixels(final Bitmap pBitmap, final PixelFormat pPixelFormat, final ByteOrder pByteOrder) {
final int[] pixelsARGB_8888 = GLHelper.getPixelsARGB_8888(pBitmap);
switch(pPixelFormat) {
case RGB_565:
return ShortBuffer.wrap(GLHelper.convertARGB_8888toRGB_565(pixelsARGB_8888, pByteOrder)); // TODO Is ShortBuffer or IntBuffer faster?
case RGBA_8888:
// HACK =(
final ByteOrder reverseByteOrder = (pByteOrder == ByteOrder.LITTLE_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
return IntBuffer.wrap(GLHelper.convertARGB_8888toRGBA_8888(pixelsARGB_8888, reverseByteOrder));
case RGBA_4444:
return ShortBuffer.wrap(GLHelper.convertARGB_8888toRGBA_4444(pixelsARGB_8888, pByteOrder)); // TODO Is ShortBuffer or IntBuffer faster?
case A_8:
return ByteBuffer.wrap(GLHelper.convertARGB_8888toA_8(pixelsARGB_8888));
default:
throw new IllegalArgumentException("Unexpected " + PixelFormat.class.getSimpleName() + ": '" + pPixelFormat + "'.");
}
}
public static int[] convertARGB_8888toRGBA_8888(final int[] pPixelsARGB_8888) {
return GLHelper.convertARGB_8888toRGBA_8888(pPixelsARGB_8888, ByteOrder.nativeOrder());
}
public static int[] convertARGB_8888toRGBA_8888(final int[] pPixelsARGB_8888, final ByteOrder pByteOrder) {
if(pByteOrder == ByteOrder.LITTLE_ENDIAN) {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [A][B][G][R] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 | B7 B6 B5 B4 B3 B2 B1 B0 | G7 G6 G5 G4 G3 G2 G1 G0 | R7 R6 R5 R4 R3 R2 R1 R0 ] */
pPixelsARGB_8888[i] = (pixel & 0xFF00FF00) | ((pixel << 16) & 0x00FF0000) | ((pixel >> 16) & 0x000000FF);
}
} else {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [R][G][B][A] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 | A7 A6 A5 A4 A3 A2 A1 A0 ] */
pPixelsARGB_8888[i] = ((pixel << 8) & 0xFFFFFF00) | ((pixel >> 24) & 0x000000FF);
}
}
return pPixelsARGB_8888;
}
public static short[] convertARGB_8888toRGB_565(final int[] pPixelsARGB_8888) {
return GLHelper.convertARGB_8888toRGB_565(pPixelsARGB_8888, ByteOrder.nativeOrder());
}
public static short[] convertARGB_8888toRGB_565(final int[] pPixelsARGB_8888, final ByteOrder pByteOrder) {
final short[] pixelsRGB_565 = new short[pPixelsARGB_8888.length];
if(pByteOrder == ByteOrder.LITTLE_ENDIAN) {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [GB][RG] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ G4 G3 G2 B7 B6 B5 B4 B5 | R7 R6 R5 R4 R3 G7 G6 G5 ] */
/* pixelsRGB_565[i] = (short)(red | green | blue); */
pixelsRGB_565[i] = (short)(((pixel >> 16) & 0x00F8) | ((pixel >> 13) & 0x07) | ((pixel << 3) & 0xE000) | ((pixel << 5) & 0x1F00));
}
} else {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [RG][GB] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ R7 R6 R5 R4 R3 G7 G6 G5 | G4 G3 G2 B7 B6 B5 B4 B3 ] */
/* pixelsRGB_565[i] = (short)(red | green | blue); */
pixelsRGB_565[i] = (short)(((pixel >> 8) & 0xF800) | ((pixel >> 5) & 0x07E0) | ((pixel >> 3) & 0x001F));
}
}
return pixelsRGB_565;
}
public static short[] convertARGB_8888toRGBA_4444(final int[] pPixelsARGB_8888) {
return GLHelper.convertARGB_8888toRGBA_4444(pPixelsARGB_8888, ByteOrder.nativeOrder());
}
public static short[] convertARGB_8888toRGBA_4444(final int[] pPixelsARGB_8888, final ByteOrder pByteOrder) {
final short[] pixelsRGBA_4444 = new short[pPixelsARGB_8888.length];
if(pByteOrder == ByteOrder.LITTLE_ENDIAN) {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [BA][RG] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ B7 B6 B5 B4 A7 A6 A5 A4 | R7 R6 R5 R4 G7 G6 G5 G4 ] */
/* pixelsRGBA_4444[i] = (short)(red | green | blue | alpha) */
pixelsRGBA_4444[i] = (short)(((pixel >> 16) & 0x00F0) | ((pixel >> 12) & 0x000F) | ((pixel << 8) & 0xF000) | ((pixel >> 20) & 0x0F00));
}
} else {
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsARGB_8888[i];
/* [A][R][G][B] to [RG][BA] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ R7 R6 R5 R4 G7 G6 G5 G4 | B7 B6 B5 B4 A7 A6 A5 A4 ] */
/* pixelsRGBA_4444[i] = (short)(red | green | blue | alpha) */
pixelsRGBA_4444[i] = (short)(((pixel >> 8) & 0xF000) | ((pixel >> 4) & 0x0F00) | ((pixel) & 0x00F0) | ((pixel >> 28) & 0x0000F));
}
}
return pixelsRGBA_4444;
}
public static byte[] convertARGB_8888toA_8(final int[] pPixelsARGB_8888) {
final byte[] pixelsA_8 = new byte[pPixelsARGB_8888.length];
for(int i = pPixelsARGB_8888.length - 1; i >= 0; i--) {
/* [A][R][G][B] to [A] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 ] */
pixelsA_8[i] = (byte) ((pPixelsARGB_8888[i] >> 24) & 0xFF);
}
return pixelsA_8;
}
public static int[] getPixelsARGB_8888(final Bitmap pBitmap) {
final int w = pBitmap.getWidth();
final int h = pBitmap.getHeight();
final int[] pixelsARGB_8888 = new int[w * h];
pBitmap.getPixels(pixelsARGB_8888, 0, w, 0, 0, w, h);
return pixelsARGB_8888;
}
public static int[] convertRGBA_8888toARGB_8888(final int[] pPixelsRGBA_8888) {
return GLHelper.convertRGBA_8888toARGB_8888(pPixelsRGBA_8888, ByteOrder.nativeOrder());
}
public static int[] convertRGBA_8888toARGB_8888(final int[] pPixelsRGBA_8888, final ByteOrder pByteOrder) {
if(pByteOrder == ByteOrder.LITTLE_ENDIAN) {
for(int i = pPixelsRGBA_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsRGBA_8888[i];
/* [A][B][G][R] to [A][R][G][B] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | B7 B6 B5 B4 B3 B2 B1 B0 | G7 G6 G5 G4 G3 G2 G1 G0 | R7 R6 R5 R4 R3 R2 R1 R0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
pPixelsRGBA_8888[i] = (pixel & 0xFF00FF00) | ((pixel << 16) & 0x00FF0000) | ((pixel >> 16) & 0x000000FF);
}
} else {
for(int i = pPixelsRGBA_8888.length - 1; i >= 0; i--) {
final int pixel = pPixelsRGBA_8888[i];
/* [R][G][B][A] to [A][R][G][B] */
/* From : [ R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 | A7 A6 A5 A4 A3 A2 A1 A0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
pPixelsRGBA_8888[i] = ((pixel >> 8) & 0x00FFFFFF) | ((pixel << 24) & 0xFF000000);
}
}
return pPixelsRGBA_8888;
}
public static int[] convertRGBA_8888toARGB_8888_FlippedVertical(final int[] pPixelsRGBA_8888, final int pWidth, final int pHeight) {
return GLHelper.convertRGBA_8888toARGB_8888_FlippedVertical(pPixelsRGBA_8888, pWidth, pHeight, ByteOrder.nativeOrder());
}
public static int[] convertRGBA_8888toARGB_8888_FlippedVertical(final int[] pPixelsRGBA_8888, final int pWidth, final int pHeight, final ByteOrder pByteOrder) {
final int[] pixelsARGB_8888 = new int[pWidth * pHeight];
if(pByteOrder == ByteOrder.LITTLE_ENDIAN) {
for(int y = 0; y < pHeight; y++) {
for(int x = 0; x < pWidth; x++) {
final int pixel = pPixelsRGBA_8888[x + (y * pWidth)];
/* [A][B][G][R] to [A][R][G][B] */
/* From : [ A7 A6 A5 A4 A3 A2 A1 A0 | B7 B6 B5 B4 B3 B2 B1 B0 | G7 G6 G5 G4 G3 G2 G1 G0 | R7 R6 R5 R4 R3 R2 R1 R0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
pixelsARGB_8888[x + ((pHeight - y - 1) * pWidth)] = (pixel & 0xFF00FF00) | ((pixel << 16) & 0x00FF0000) | ((pixel >> 16) & 0x000000FF);
}
}
} else {
for(int y = 0; y < pHeight; y++) {
for(int x = 0; x < pWidth; x++) {
final int pixel = pPixelsRGBA_8888[x + (y * pWidth)];
/* [R][G][B][A] to [A][R][G][B] */
/* From : [ R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 | A7 A6 A5 A4 A3 A2 A1 A0 ] */
/* To : [ A7 A6 A5 A4 A3 A2 A1 A0 | R7 R6 R5 R4 R3 R2 R1 R0 | G7 G6 G5 G4 G3 G2 G1 G0 | B7 B6 B5 B4 B3 B2 B1 B0 ] */
pixelsARGB_8888[x + ((pHeight - y - 1) * pWidth)] = ((pixel >> 8) & 0x00FFFFFF) | ((pixel << 24) & 0xFF000000);
}
}
}
return pixelsARGB_8888;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}