Committed a patch for ARGB8 and BGRA8 support

http://hub.jmonkeyengine.org/forum/topic/support-for-argb8-and-bgra8-textures/#260706

Also made the change for Jogl TextureUtil as it was missing from the patch

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@11086 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
rem..om 11 years ago
parent 8c2c62d01f
commit df66664f98
  1. 10
      engine/src/core/com/jme3/texture/Image.java
  2. 4
      engine/src/core/com/jme3/texture/image/ImageCodec.java
  3. 964
      engine/src/desktop/jme3tools/converters/ImageToAwt.java
  4. 2
      engine/src/jogl/com/jme3/renderer/jogl/TextureUtil.java
  5. 2
      engine/src/lwjgl/com/jme3/renderer/lwjgl/TextureUtil.java

@ -148,6 +148,16 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ {
* 8-bit alpha, blue, green, and red. * 8-bit alpha, blue, green, and red.
*/ */
ABGR8(32), ABGR8(32),
/**
* 8-bit alpha, red, blue and green
*/
ARGB8(32),
/**
* 8-bit blue, green, red and alpha.
*/
BGRA8(32),
/** /**
* 16-bit red, green, blue and alpha * 16-bit red, green, blue and alpha

@ -134,6 +134,10 @@ abstract class ImageCodec {
params.put(Format.ABGR8, new ByteOffsetImageCodec(4, 0, 0, 3, 2, 1)); params.put(Format.ABGR8, new ByteOffsetImageCodec(4, 0, 0, 3, 2, 1));
params.put(Format.ARGB8, new ByteOffsetImageCodec(4, 0, 0, 1, 2, 3));
params.put(Format.BGRA8, new ByteOffsetImageCodec(4, 0, 3, 2, 1, 0));
params.put(Format.ARGB4444, new BitMaskImageCodec(2, 0, params.put(Format.ARGB4444, new BitMaskImageCodec(2, 0,
4, 4, 4, 4, 4, 4, 4, 4,
12, 0, 4, 8)); 12, 0, 4, 8));

@ -1,478 +1,486 @@
/* /*
* Copyright (c) 2009-2012 jMonkeyEngine * Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
* met: * met:
* *
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package jme3tools.converters; package jme3tools.converters;
import com.jme3.texture.Image; import com.jme3.texture.Image;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
import com.jme3.texture.plugins.AWTLoader; import com.jme3.texture.plugins.AWTLoader;
import com.jme3.util.BufferUtils; import com.jme3.util.BufferUtils;
import java.awt.Transparency; import java.awt.Transparency;
import java.awt.color.ColorSpace; import java.awt.color.ColorSpace;
import java.awt.image.*; import java.awt.image.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.EnumMap; import java.util.EnumMap;
public class ImageToAwt { public class ImageToAwt {
private static final EnumMap<Format, DecodeParams> params private static final EnumMap<Format, DecodeParams> params
= new EnumMap<Format, DecodeParams>(Format.class); = new EnumMap<Format, DecodeParams>(Format.class);
private static class DecodeParams { private static class DecodeParams {
final int bpp, am, rm, gm, bm, as, rs, gs, bs, im, is; final int bpp, am, rm, gm, bm, as, rs, gs, bs, im, is;
public DecodeParams(int bpp, int am, int rm, int gm, int bm, int as, int rs, int gs, int bs, int im, int is) { public DecodeParams(int bpp, int am, int rm, int gm, int bm, int as, int rs, int gs, int bs, int im, int is) {
this.bpp = bpp; this.bpp = bpp;
this.am = am; this.am = am;
this.rm = rm; this.rm = rm;
this.gm = gm; this.gm = gm;
this.bm = bm; this.bm = bm;
this.as = as; this.as = as;
this.rs = rs; this.rs = rs;
this.gs = gs; this.gs = gs;
this.bs = bs; this.bs = bs;
this.im = im; this.im = im;
this.is = is; this.is = is;
} }
public DecodeParams(int bpp, int rm, int rs, int im, int is, boolean alpha){ public DecodeParams(int bpp, int rm, int rs, int im, int is, boolean alpha){
this.bpp = bpp; this.bpp = bpp;
if (alpha){ if (alpha){
this.am = rm; this.am = rm;
this.as = rs; this.as = rs;
this.rm = 0; this.rm = 0;
this.rs = 0; this.rs = 0;
}else{ }else{
this.rm = rm; this.rm = rm;
this.rs = rs; this.rs = rs;
this.am = 0; this.am = 0;
this.as = 0; this.as = 0;
} }
this.gm = 0; this.gm = 0;
this.bm = 0; this.bm = 0;
this.gs = 0; this.gs = 0;
this.bs = 0; this.bs = 0;
this.im = im; this.im = im;
this.is = is; this.is = is;
} }
public DecodeParams(int bpp, int rm, int rs, int im, int is){ public DecodeParams(int bpp, int rm, int rs, int im, int is){
this(bpp, rm, rs, im, is, false); this(bpp, rm, rs, im, is, false);
} }
} }
static { static {
final int mx___ = 0xff000000; final int mx___ = 0xff000000;
final int m_x__ = 0x00ff0000; final int m_x__ = 0x00ff0000;
final int m__x_ = 0x0000ff00; final int m__x_ = 0x0000ff00;
final int m___x = 0x000000ff; final int m___x = 0x000000ff;
final int sx___ = 24; final int sx___ = 24;
final int s_x__ = 16; final int s_x__ = 16;
final int s__x_ = 8; final int s__x_ = 8;
final int s___x = 0; final int s___x = 0;
final int mxxxx = 0xffffffff; final int mxxxx = 0xffffffff;
final int sxxxx = 0; final int sxxxx = 0;
final int m4x___ = 0xf000; final int m4x___ = 0xf000;
final int m4_x__ = 0x0f00; final int m4_x__ = 0x0f00;
final int m4__x_ = 0x00f0; final int m4__x_ = 0x00f0;
final int m4___x = 0x000f; final int m4___x = 0x000f;
final int s4x___ = 12; final int s4x___ = 12;
final int s4_x__ = 8; final int s4_x__ = 8;
final int s4__x_ = 4; final int s4__x_ = 4;
final int s4___x = 0; final int s4___x = 0;
final int m5___ = 0xf800; final int m5___ = 0xf800;
final int m_5__ = 0x07c0; final int m_5__ = 0x07c0;
final int m__5_ = 0x003e; final int m__5_ = 0x003e;
final int m___1 = 0x0001; final int m___1 = 0x0001;
final int s5___ = 11; final int s5___ = 11;
final int s_5__ = 6; final int s_5__ = 6;
final int s__5_ = 1; final int s__5_ = 1;
final int s___1 = 0; final int s___1 = 0;
final int m5__ = 0xf800; final int m5__ = 0xf800;
final int m_6_ = 0x07e0; final int m_6_ = 0x07e0;
final int m__5 = 0x001f; final int m__5 = 0x001f;
final int s5__ = 11; final int s5__ = 11;
final int s_6_ = 5; final int s_6_ = 5;
final int s__5 = 0; final int s__5 = 0;
final int mxx__ = 0xffff0000; final int mxx__ = 0xffff0000;
final int sxx__ = 32; final int sxx__ = 32;
final int m__xx = 0x0000ffff; final int m__xx = 0x0000ffff;
final int s__xx = 0; final int s__xx = 0;
// note: compressed, depth, or floating point formats not included here.. // note: compressed, depth, or floating point formats not included here..
params.put(Format.ABGR8, new DecodeParams(4, mx___, m___x, m__x_, m_x__, params.put(Format.ABGR8, new DecodeParams(4, mx___, m___x, m__x_, m_x__,
sx___, s___x, s__x_, s_x__, sx___, s___x, s__x_, s_x__,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.ARGB4444, new DecodeParams(2, m4x___, m4_x__, m4__x_, m4___x, params.put(Format.ARGB4444, new DecodeParams(2, m4x___, m4_x__, m4__x_, m4___x,
s4x___, s4_x__, s4__x_, s4___x, s4x___, s4_x__, s4__x_, s4___x,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.Alpha16, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, true)); params.put(Format.Alpha16, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, true));
params.put(Format.Alpha8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, true)); params.put(Format.Alpha8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, true));
params.put(Format.BGR8, new DecodeParams(3, 0, m___x, m__x_, m_x__, params.put(Format.BGR8, new DecodeParams(3, 0, m___x, m__x_, m_x__,
0, s___x, s__x_, s_x__, 0, s___x, s__x_, s_x__,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.Luminance16, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false)); params.put(Format.Luminance16, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false));
params.put(Format.Luminance8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false)); params.put(Format.Luminance8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false));
params.put(Format.Luminance16Alpha16, new DecodeParams(4, m__xx, mxx__, 0, 0, params.put(Format.Luminance16Alpha16, new DecodeParams(4, m__xx, mxx__, 0, 0,
s__xx, sxx__, 0, 0, s__xx, sxx__, 0, 0,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.Luminance16F, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false)); params.put(Format.Luminance16F, new DecodeParams(2, mxxxx, sxxxx, mxxxx, sxxxx, false));
params.put(Format.Luminance16FAlpha16F, new DecodeParams(4, m__xx, mxx__, 0, 0, params.put(Format.Luminance16FAlpha16F, new DecodeParams(4, m__xx, mxx__, 0, 0,
s__xx, sxx__, 0, 0, s__xx, sxx__, 0, 0,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.Luminance32F, new DecodeParams(4, mxxxx, sxxxx, mxxxx, sxxxx, false)); params.put(Format.Luminance32F, new DecodeParams(4, mxxxx, sxxxx, mxxxx, sxxxx, false));
params.put(Format.Luminance8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false)); params.put(Format.Luminance8, new DecodeParams(1, mxxxx, sxxxx, mxxxx, sxxxx, false));
params.put(Format.RGB5A1, new DecodeParams(2, m___1, m5___, m_5__, m__5_, params.put(Format.RGB5A1, new DecodeParams(2, m___1, m5___, m_5__, m__5_,
s___1, s5___, s_5__, s__5_, s___1, s5___, s_5__, s__5_,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.RGB565, new DecodeParams(2, 0, m5__ , m_6_ , m__5, params.put(Format.RGB565, new DecodeParams(2, 0, m5__ , m_6_ , m__5,
0, s5__ , s_6_ , s__5, 0, s5__ , s_6_ , s__5,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.RGB8, new DecodeParams(3, 0, m_x__, m__x_, m___x, params.put(Format.RGB8, new DecodeParams(3, 0, m_x__, m__x_, m___x,
0, s_x__, s__x_, s___x, 0, s_x__, s__x_, s___x,
mxxxx, sxxxx)); mxxxx, sxxxx));
params.put(Format.RGBA8, new DecodeParams(4, m___x, mx___, m_x__, m__x_, params.put(Format.RGBA8, new DecodeParams(4, m___x, mx___, m_x__, m__x_,
s___x, sx___, s_x__, s__x_, s___x, sx___, s_x__, s__x_,
mxxxx, sxxxx)); mxxxx, sxxxx));
} params.put(Format.BGRA8, new DecodeParams(4, m___x, m__x_, m_x__, mx___,
s___x, s__x_, s_x__, sx___,
private static int Ix(int x, int y, int w){ mxxxx, sxxxx));
return y * w + x;
} params.put(Format.ARGB8, new DecodeParams(4, mx___, m_x__, m__x_, m___x,
sx___, s_x__, s__x_, s___x,
private static int readPixel(ByteBuffer buf, int idx, int bpp){ mxxxx, sxxxx));
buf.position(idx);
int original = buf.get() & 0xff; }
while ((--bpp) > 0){
original = (original << 8) | (buf.get() & 0xff); private static int Ix(int x, int y, int w){
} return y * w + x;
return original; }
}
private static int readPixel(ByteBuffer buf, int idx, int bpp){
private static void writePixel(ByteBuffer buf, int idx, int pixel, int bpp){ buf.position(idx);
buf.position(idx); int original = buf.get() & 0xff;
while ((--bpp) >= 0){ while ((--bpp) > 0){
// pixel = pixel >> 8; original = (original << 8) | (buf.get() & 0xff);
byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff); }
// buf.put( (byte) (pixel & 0xff) ); return original;
buf.put(bt); }
}
} private static void writePixel(ByteBuffer buf, int idx, int pixel, int bpp){
buf.position(idx);
while ((--bpp) >= 0){
/** // pixel = pixel >> 8;
* Convert an AWT image to jME image. byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff);
*/ // buf.put( (byte) (pixel & 0xff) );
public static void convert(BufferedImage image, Format format, ByteBuffer buf){ buf.put(bt);
DecodeParams p = params.get(format); }
if (p == null) }
throw new UnsupportedOperationException("Image format " + format + " is not supported");
int width = image.getWidth(); /**
int height = image.getHeight(); * Convert an AWT image to jME image.
*/
boolean alpha = true; public static void convert(BufferedImage image, Format format, ByteBuffer buf){
boolean luminance = false; DecodeParams p = params.get(format);
if (p == null)
int reductionA = 8 - Integer.bitCount(p.am); throw new UnsupportedOperationException("Image format " + format + " is not supported");
int reductionR = 8 - Integer.bitCount(p.rm);
int reductionG = 8 - Integer.bitCount(p.gm); int width = image.getWidth();
int reductionB = 8 - Integer.bitCount(p.bm); int height = image.getHeight();
int initialPos = buf.position(); boolean alpha = true;
for (int y = 0; y < height; y++){ boolean luminance = false;
for (int x = 0; x < width; x++){
// Get ARGB int reductionA = 8 - Integer.bitCount(p.am);
int argb = image.getRGB(x, y); int reductionR = 8 - Integer.bitCount(p.rm);
int reductionG = 8 - Integer.bitCount(p.gm);
// Extract color components int reductionB = 8 - Integer.bitCount(p.bm);
int a = (argb & 0xff000000) >> 24;
int r = (argb & 0x00ff0000) >> 16; int initialPos = buf.position();
int g = (argb & 0x0000ff00) >> 8; for (int y = 0; y < height; y++){
int b = (argb & 0x000000ff); for (int x = 0; x < width; x++){
// Get ARGB
// Remove anything after 8 bits int argb = image.getRGB(x, y);
a = a & 0xff;
r = r & 0xff; // Extract color components
g = g & 0xff; int a = (argb & 0xff000000) >> 24;
b = b & 0xff; int r = (argb & 0x00ff0000) >> 16;
int g = (argb & 0x0000ff00) >> 8;
// Set full alpha if target image has no alpha int b = (argb & 0x000000ff);
if (!alpha)
a = 0xff; // Remove anything after 8 bits
a = a & 0xff;
// Convert color to luminance if target r = r & 0xff;
// image is in luminance format g = g & 0xff;
if (luminance){ b = b & 0xff;
// convert RGB to luminance
} // Set full alpha if target image has no alpha
if (!alpha)
// Do bit reduction, assumes proper rounding has already been a = 0xff;
// done.
a = a >> reductionA; // Convert color to luminance if target
r = r >> reductionR; // image is in luminance format
g = g >> reductionG; if (luminance){
b = b >> reductionB; // convert RGB to luminance
}
// Put components into appropriate positions
a = (a << p.as) & p.am; // Do bit reduction, assumes proper rounding has already been
r = (r << p.rs) & p.rm; // done.
g = (g << p.gs) & p.gm; a = a >> reductionA;
b = (b << p.bs) & p.bm; r = r >> reductionR;
g = g >> reductionG;
int outputPixel = ((a | r | g | b) << p.is) & p.im; b = b >> reductionB;
int i = initialPos + (Ix(x,y,width) * p.bpp);
writePixel(buf, i, outputPixel, p.bpp); // Put components into appropriate positions
} a = (a << p.as) & p.am;
} r = (r << p.rs) & p.rm;
} g = (g << p.gs) & p.gm;
b = (b << p.bs) & p.bm;
private static final double LOG2 = Math.log(2);
int outputPixel = ((a | r | g | b) << p.is) & p.im;
public static void createData(Image image, boolean mipmaps){ int i = initialPos + (Ix(x,y,width) * p.bpp);
int bpp = image.getFormat().getBitsPerPixel(); writePixel(buf, i, outputPixel, p.bpp);
int w = image.getWidth(); }
int h = image.getHeight(); }
if (!mipmaps){ }
image.setData(BufferUtils.createByteBuffer(w*h*bpp/8));
return; private static final double LOG2 = Math.log(2);
}
int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(h, w)) / LOG2); public static void createData(Image image, boolean mipmaps){
int[] mipMapSizes = new int[expectedMipmaps]; int bpp = image.getFormat().getBitsPerPixel();
int total = 0; int w = image.getWidth();
for (int i = 0; i < mipMapSizes.length; i++){ int h = image.getHeight();
int size = (w * h * bpp) / 8; if (!mipmaps){
total += size; image.setData(BufferUtils.createByteBuffer(w*h*bpp/8));
mipMapSizes[i] = size; return;
w /= 2; }
h /= 2; int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(h, w)) / LOG2);
} int[] mipMapSizes = new int[expectedMipmaps];
image.setMipMapSizes(mipMapSizes); int total = 0;
image.setData(BufferUtils.createByteBuffer(total)); for (int i = 0; i < mipMapSizes.length; i++){
} int size = (w * h * bpp) / 8;
total += size;
/** mipMapSizes[i] = size;
* Convert the image from the given format to the output format. w /= 2;
* It is assumed that both images have buffers with the appropriate h /= 2;
* number of elements and that both have the same dimensions. }
* image.setMipMapSizes(mipMapSizes);
* @param input image.setData(BufferUtils.createByteBuffer(total));
* @param output }
*/
public static void convert(Image input, Image output){ /**
DecodeParams inParams = params.get(input.getFormat()); * Convert the image from the given format to the output format.
DecodeParams outParams = params.get(output.getFormat()); * It is assumed that both images have buffers with the appropriate
* number of elements and that both have the same dimensions.
if (inParams == null || outParams == null) *
throw new UnsupportedOperationException(); * @param input
* @param output
int width = input.getWidth(); */
int height = input.getHeight(); public static void convert(Image input, Image output){
DecodeParams inParams = params.get(input.getFormat());
if (width != output.getWidth() || height != output.getHeight()) DecodeParams outParams = params.get(output.getFormat());
throw new IllegalArgumentException();
if (inParams == null || outParams == null)
ByteBuffer inData = input.getData(0); throw new UnsupportedOperationException();
boolean inAlpha = false; int width = input.getWidth();
boolean inLum = false; int height = input.getHeight();
boolean inRGB = false;
if (inParams.am != 0) { if (width != output.getWidth() || height != output.getHeight())
inAlpha = true; throw new IllegalArgumentException();
}
ByteBuffer inData = input.getData(0);
if (inParams.rm != 0 && inParams.gm == 0 && inParams.bm == 0) {
inLum = true; boolean inAlpha = false;
} else if (inParams.rm != 0 && inParams.gm != 0 && inParams.bm != 0) { boolean inLum = false;
inRGB = true; boolean inRGB = false;
} if (inParams.am != 0) {
inAlpha = true;
int expansionA = 8 - Integer.bitCount(inParams.am); }
int expansionR = 8 - Integer.bitCount(inParams.rm);
int expansionG = 8 - Integer.bitCount(inParams.gm); if (inParams.rm != 0 && inParams.gm == 0 && inParams.bm == 0) {
int expansionB = 8 - Integer.bitCount(inParams.bm); inLum = true;
} else if (inParams.rm != 0 && inParams.gm != 0 && inParams.bm != 0) {
int inputPixel; inRGB = true;
for (int y = 0; y < height; y++){ }
for (int x = 0; x < width; x++){
int i = Ix(x, y, width) * inParams.bpp; int expansionA = 8 - Integer.bitCount(inParams.am);
inputPixel = (readPixel(inData, i, inParams.bpp) & inParams.im) >> inParams.is; int expansionR = 8 - Integer.bitCount(inParams.rm);
int expansionG = 8 - Integer.bitCount(inParams.gm);
int a = (inputPixel & inParams.am) >> inParams.as; int expansionB = 8 - Integer.bitCount(inParams.bm);
int r = (inputPixel & inParams.rm) >> inParams.rs;
int g = (inputPixel & inParams.gm) >> inParams.gs; int inputPixel;
int b = (inputPixel & inParams.bm) >> inParams.bs; for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
r = r & 0xff; int i = Ix(x, y, width) * inParams.bpp;
g = g & 0xff; inputPixel = (readPixel(inData, i, inParams.bpp) & inParams.im) >> inParams.is;
b = b & 0xff;
a = a & 0xff; int a = (inputPixel & inParams.am) >> inParams.as;
int r = (inputPixel & inParams.rm) >> inParams.rs;
a = a << expansionA; int g = (inputPixel & inParams.gm) >> inParams.gs;
r = r << expansionR; int b = (inputPixel & inParams.bm) >> inParams.bs;
g = g << expansionG;
b = b << expansionB; r = r & 0xff;
g = g & 0xff;
if (inLum) b = b & 0xff;
b = g = r; a = a & 0xff;
if (!inAlpha) a = a << expansionA;
a = 0xff; r = r << expansionR;
g = g << expansionG;
// int argb = (a << 24) | (r << 16) | (g << 8) | b; b = b << expansionB;
// out.setRGB(x, y, argb);
} if (inLum)
} b = g = r;
}
if (!inAlpha)
public static BufferedImage convert(Image image, boolean do16bit, boolean fullalpha, int mipLevel){ a = 0xff;
Format format = image.getFormat();
DecodeParams p = params.get(image.getFormat()); // int argb = (a << 24) | (r << 16) | (g << 8) | b;
if (p == null) // out.setRGB(x, y, argb);
throw new UnsupportedOperationException(); }
}
int width = image.getWidth(); }
int height = image.getHeight();
public static BufferedImage convert(Image image, boolean do16bit, boolean fullalpha, int mipLevel){
int level = mipLevel; Format format = image.getFormat();
while (--level >= 0){ DecodeParams p = params.get(image.getFormat());
width /= 2; if (p == null)
height /= 2; throw new UnsupportedOperationException();
}
int width = image.getWidth();
ByteBuffer buf = image.getData(0); int height = image.getHeight();
buf.order(ByteOrder.LITTLE_ENDIAN);
int level = mipLevel;
BufferedImage out; while (--level >= 0){
width /= 2;
boolean alpha = false; height /= 2;
boolean luminance = false; }
boolean rgb = false;
if (p.am != 0) ByteBuffer buf = image.getData(0);
alpha = true; buf.order(ByteOrder.LITTLE_ENDIAN);
if (p.rm != 0 && p.gm == 0 && p.bm == 0) BufferedImage out;
luminance = true;
else if (p.rm != 0 && p.gm != 0 && p.bm != 0) boolean alpha = false;
rgb = true; boolean luminance = false;
boolean rgb = false;
// alpha OR luminance but not both if (p.am != 0)
if ( (alpha && !rgb && !luminance) || (luminance && !alpha && !rgb) ){ alpha = true;
out = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
}else if ( (rgb && alpha) || (luminance && alpha) ){ if (p.rm != 0 && p.gm == 0 && p.bm == 0)
if (do16bit){ luminance = true;
if (fullalpha){ else if (p.rm != 0 && p.gm != 0 && p.bm != 0)
ColorModel model = AWTLoader.AWT_RGBA4444; rgb = true;
WritableRaster raster = model.createCompatibleWritableRaster(width, width);
out = new BufferedImage(model, raster, false, null); // alpha OR luminance but not both
}else{ if ( (alpha && !rgb && !luminance) || (luminance && !alpha && !rgb) ){
// RGB5_A1 out = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); }else if ( (rgb && alpha) || (luminance && alpha) ){
int[] nBits = {5, 5, 5, 1}; if (do16bit){
int[] bOffs = {0, 1, 2, 3}; if (fullalpha){
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false, ColorModel model = AWTLoader.AWT_RGBA4444;
Transparency.BITMASK, WritableRaster raster = model.createCompatibleWritableRaster(width, width);
DataBuffer.TYPE_BYTE); out = new BufferedImage(model, raster, false, null);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, }else{
width, height, // RGB5_A1
width*2, 2, ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
bOffs, null); int[] nBits = {5, 5, 5, 1};
out = new BufferedImage(colorModel, raster, false, null); int[] bOffs = {0, 1, 2, 3};
} ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
}else{ Transparency.BITMASK,
out = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); DataBuffer.TYPE_BYTE);
} WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
}else{ width, height,
if (do16bit){ width*2, 2,
out = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB); bOffs, null);
}else{ out = new BufferedImage(colorModel, raster, false, null);
out = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); }
} }else{
} out = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
int expansionA = 8 - Integer.bitCount(p.am); }else{
int expansionR = 8 - Integer.bitCount(p.rm); if (do16bit){
int expansionG = 8 - Integer.bitCount(p.gm); out = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_565_RGB);
int expansionB = 8 - Integer.bitCount(p.bm); }else{
out = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
if (expansionR < 0){ }
expansionR = 0; }
}
int expansionA = 8 - Integer.bitCount(p.am);
int mipPos = 0; int expansionR = 8 - Integer.bitCount(p.rm);
for (int i = 0; i < mipLevel; i++){ int expansionG = 8 - Integer.bitCount(p.gm);
mipPos += image.getMipMapSizes()[i]; int expansionB = 8 - Integer.bitCount(p.bm);
}
int inputPixel; if (expansionR < 0){
for (int y = 0; y < height; y++){ expansionR = 0;
for (int x = 0; x < width; x++){ }
int i = mipPos + (Ix(x,y,width) * p.bpp);
inputPixel = (readPixel(buf,i,p.bpp) & p.im) >> p.is; int mipPos = 0;
int a = (inputPixel & p.am) >> p.as; for (int i = 0; i < mipLevel; i++){
int r = (inputPixel & p.rm) >> p.rs; mipPos += image.getMipMapSizes()[i];
int g = (inputPixel & p.gm) >> p.gs; }
int b = (inputPixel & p.bm) >> p.bs; int inputPixel;
for (int y = 0; y < height; y++){
r = r & 0xff; for (int x = 0; x < width; x++){
g = g & 0xff; int i = mipPos + (Ix(x,y,width) * p.bpp);
b = b & 0xff; inputPixel = (readPixel(buf,i,p.bpp) & p.im) >> p.is;
a = a & 0xff; int a = (inputPixel & p.am) >> p.as;
int r = (inputPixel & p.rm) >> p.rs;
a = a << expansionA; int g = (inputPixel & p.gm) >> p.gs;
r = r << expansionR; int b = (inputPixel & p.bm) >> p.bs;
g = g << expansionG;
b = b << expansionB; r = r & 0xff;
g = g & 0xff;
if (luminance) b = b & 0xff;
b = g = r; a = a & 0xff;
if (!alpha) a = a << expansionA;
a = 0xff; r = r << expansionR;
g = g << expansionG;
int argb = (a << 24) | (r << 16) | (g << 8) | b; b = b << expansionB;
out.setRGB(x, y, argb);
} if (luminance)
} b = g = r;
return out; if (!alpha)
} a = 0xff;
} int argb = (a << 24) | (r << 16) | (g << 8) | b;
out.setRGB(x, y, argb);
}
}
return out;
}
}

@ -123,6 +123,8 @@ public class TextureUtil {
// RGB formats // RGB formats
setFormat(Format.BGR8, GL.GL_RGB8, GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE, false); setFormat(Format.BGR8, GL.GL_RGB8, GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE, false);
setFormat(Format.ARGB8, GL.GL_RGBA8, GL.GL_BGRA, GL2.GL_UNSIGNED_INT_8_8_8_8_REV, false);
setFormat(Format.BGRA8, GL.GL_RGBA8, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, false);
setFormat(Format.RGB8, GL.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, false); setFormat(Format.RGB8, GL.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, false);
// setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false); // setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false);
setFormat(Format.RGB16, GL2GL3.GL_RGB16, GL.GL_RGB, GL.GL_UNSIGNED_SHORT, false); setFormat(Format.RGB16, GL2GL3.GL_RGB16, GL.GL_RGB, GL.GL_UNSIGNED_SHORT, false);

@ -107,6 +107,8 @@ class TextureUtil {
// RGB formats // RGB formats
setFormat(Format.BGR8, GL11.GL_RGB8, EXTBgra.GL_BGR_EXT, GL11.GL_UNSIGNED_BYTE, false); setFormat(Format.BGR8, GL11.GL_RGB8, EXTBgra.GL_BGR_EXT, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.ARGB8, GL11.GL_RGBA8, EXTBgra.GL_BGRA_EXT, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, false);
setFormat(Format.BGRA8, GL11.GL_RGBA8, EXTBgra.GL_BGRA_EXT, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.RGB8, GL11.GL_RGB8, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, false); setFormat(Format.RGB8, GL11.GL_RGB8, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, false);
// setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false); // setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false);
setFormat(Format.RGB16, GL11.GL_RGB16, GL11.GL_RGB, GL11.GL_UNSIGNED_SHORT, false); setFormat(Format.RGB16, GL11.GL_RGB16, GL11.GL_RGB, GL11.GL_UNSIGNED_SHORT, false);

Loading…
Cancel
Save