com.jogamp.nativewindow.util.PixelFormat Maven / Gradle / Ivy
Show all versions of jogl-all-android Show documentation
/**
* Copyright (c) 2014 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package com.jogamp.nativewindow.util;
import java.util.Arrays;
import com.jogamp.common.util.Bitfield;
/**
* Basic pixel formats
*
* Notation follows OpenGL notation, i.e.
* name consist of all it's component names
* followed by their bit size.
*
*
* Order of component names is from lowest-bit to highest-bit.
*
*
* In case component-size is 1 byte (e.g. OpenGL data-type GL_UNSIGNED_BYTE),
* component names are ordered from lowest-byte to highest-byte.
* Note that OpenGL applies special interpretation if
* data-type is e.g. GL_UNSIGNED_8_8_8_8_REV or GL_UNSIGNED_8_8_8_8_REV.
*
*
* PixelFormat can be converted to OpenGL GLPixelAttributes
* via
*
* GLPixelAttributes glpa = GLPixelAttributes.convert(PixelFormat pixFmt, GLProfile glp);
*
*
*
* See OpenGL Specification 4.3 - February 14, 2013, Core Profile,
* Section 8.4.4 Transfer of Pixel Rectangles, p. 161-174.
*
*
*
*/
public enum PixelFormat {
/**
* Stride is 8 bits, 8 bits per pixel, 1 component of 8 bits.
* Compatible with:
*
* - OpenGL: data-format GL_ALPHA (< GL3), GL_RED (>= GL3), data-type GL_UNSIGNED_BYTE
* - AWT: none
*
*
*/
LUMINANCE(new CType[]{ CType.Y }, 1, 8, 8),
/**
* Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
*
* The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - R: 0x1F << 0
* - G: 0x3F << 5
* - B: 0x1F << 11
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5_REV
* - AWT: None
*
*
*/
RGB565(new CType[]{ CType.R, CType.G, CType.B },
new int[]{ 0x1F, 0x3F, 0x1F },
new int[]{ 0, 5, 5+6 },
16 ),
/**
* Stride is 16 bits, 16 bits per pixel, 3 {@link PackedComposition#isUniform() discrete} components.
*
* The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - B: 0x1F << 0
* - G: 0x3F << 5
* - R: 0x1F << 11
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_SHORT_5_6_5
* - AWT: None
*
*
*/
BGR565(new CType[]{ CType.B, CType.G, CType.R},
new int[]{ 0x1F, 0x3F, 0x1F },
new int[]{ 0, 5, 5+6 },
16 ),
/**
* Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
*
* The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - R: 0x1F << 0
* - G: 0x1F << 5
* - B: 0x1F << 10
* - A: 0x01 << 15
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_1_5_5_5_REV
* - AWT: None
*
*
*/
RGBA5551(new CType[]{ CType.R, CType.G, CType.B, CType.A},
new int[]{ 0x1F, 0x1F, 0x1F, 0x01 },
new int[]{ 0, 5, 5+5, 5+5+5 },
16 ),
/**
* Stride is 16 bits, 16 bits per pixel, 4 {@link PackedComposition#isUniform() discrete} components.
*
* The {@link PackedComposition#isUniform() discrete} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - A: 0x01 << 0
* - B: 0x1F << 1
* - G: 0x1F << 6
* - R: 0x1F << 11
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_SHORT_5_5_5_1
* - AWT: None
*
*
*/
ABGR1555(new CType[]{ CType.A, CType.B, CType.G, CType.R },
new int[]{ 0x01, 0x1F, 0x1F, 0x1F },
new int[]{ 0, 1, 1+5, 1+5+5 },
16 ),
/**
* Stride 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - R: 0xFF << 0
* - G: 0xFF << 8
* - B: 0xFF << 16
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGB, data-type GL_UNSIGNED_BYTE
* - AWT: None
*
*
*/
RGB888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 24),
/**
* Stride is 24 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - B: 0xFF << 0
* - G: 0xFF << 8
* - R: 0xFF << 16
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_BGR (>= GL2), data-type GL_UNSIGNED_BYTE
* - AWT: {@link java.awt.image.BufferedImage#TYPE_3BYTE_BGR TYPE_3BYTE_BGR}
*
*
*/
BGR888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 24),
/**
* Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - R: 0xFF << 0
* - G: 0xFF << 8
* - B: 0xFF << 16
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE, with alpha discarded!
* - AWT: {@link java.awt.image.BufferedImage#TYPE_INT_BGR TYPE_INT_BGR}
*
*
*/
RGBx8888(new CType[]{ CType.R, CType.G, CType.B }, 3, 8, 32),
/**
* Stride is 32 bits, 24 bits per pixel, 3 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - B: 0xFF << 0
* - G: 0xFF << 8
* - R: 0xFF << 16
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE - with alpha discarded!
* - AWT: {@link java.awt.image.BufferedImage#TYPE_INT_RGB TYPE_INT_RGB}
*
*
*/
BGRx8888(new CType[]{ CType.B, CType.G, CType.R }, 3, 8, 32),
/**
* Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - R: 0xFF << 0
* - G: 0xFF << 8
* - B: 0xFF << 16
* - A: 0xFF << 24
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_BYTE
* - AWT: None
* - PointerIcon: OSX (NSBitmapImageRep)
* - Window Icon: OSX (NSBitmapImageRep)
* - PNGJ: Scanlines
*
*
*/
RGBA8888(new CType[]{ CType.R, CType.G, CType.B, CType.A }, 4, 8, 32),
/**
* Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - A: 0xFF << 0
* - B: 0xFF << 8
* - G: 0xFF << 16
* - R: 0xFF << 24
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_RGBA, data-type GL_UNSIGNED_INT_8_8_8_8
* - AWT: {@link java.awt.image.BufferedImage#TYPE_4BYTE_ABGR TYPE_4BYTE_ABGR}
*
*
*/
ABGR8888(new CType[]{ CType.A, CType.B, CType.G, CType.R }, 4, 8, 32),
/**
* Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - A: 0xFF << 0
* - R: 0xFF << 8
* - G: 0xFF << 16
* - B: 0xFF << 24
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_INT_8_8_8_8
* - AWT: None
*
*
*/
ARGB8888(new CType[]{ CType.A, CType.R, CType.G, CType.B }, 4, 8, 32),
/**
* Stride is 32 bits, 32 bits per pixel, 4 {@link PackedComposition#isUniform() uniform} components of 8 bits.
*
* The {@link PackedComposition#isUniform() uniform} {@link PixelFormat#composition components}
* are interleaved in the order Low to High:
*
* - B: 0xFF << 0
* - G: 0xFF << 8
* - R: 0xFF << 16
* - A: 0xFF << 24
*
*
*
* Compatible with:
*
* - OpenGL: data-format GL_BGRA, data-type GL_UNSIGNED_BYTE
* - AWT: {@link java.awt.image.BufferedImage#TYPE_INT_ARGB TYPE_INT_ARGB}
* - PointerIcon: X11 (XCURSOR), Win32, AWT
* - Window Icon: X11, Win32
*
*
*/
BGRA8888(new CType[]{ CType.B, CType.G, CType.R, CType.A }, 4, 8, 32);
/** Unique {@link Composition Pixel Composition}, i.e. layout of its components. */
public final Composition comp;
/**
* @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
* @param componentCount number of components
* @param bpc bits per component
* @param bitStride stride bits to next pixel
*/
private PixelFormat(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
this.comp = new PackedComposition(componentOrder, componentCount, bpc, bitStride);
}
/**
* @param componentOrder {@link CType Component type} order of all components, see {@link Composition#componentBitMask()}.
* @param componentMask bit-mask of of all components, see {@link Composition##componentBitMask()}.
* @param componentBitShift bit-shift of all components, see {@link Composition##componentBitMask()}.
* @param bitStride stride bits to next pixel
*/
private PixelFormat(final CType[] componentOrder, final int[] componentMask, final int[] componentBitShift, final int bitStride) {
this.comp = new PackedComposition(componentOrder, componentMask, componentBitShift, bitStride);
}
/**
* Returns the unique matching {@link PixelFormat} of the given {@link Composition}
* or {@code null} if none is available.
*/
public static PixelFormat valueOf(final Composition comp) {
final PixelFormat[] all = PixelFormat.values();
for(int i=all.length-1; i>=0; i--) {
final PixelFormat pf = all[i];
if( comp.hashCode() == pf.comp.hashCode() && comp.equals(pf.comp) ) {
return pf;
}
}
return null;
}
/** Component types */
public static enum CType {
/** Red component */
R,
/** Green component */
G,
/** Blue component */
B,
/** Alpha component */
A,
/** Luminance component, e.g. grayscale or Y of YUV */
Y,
/** U component of YUV */
U,
/** V component of YUV */
V;
}
/**
* Pixel composition, i.e. layout of its components.
*/
public static interface Composition {
/** {@value} */
public static final int UNDEF = -1;
/**
* Returns {@code true} if all components are of same bit-size, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
* otherwise {@code false}, e.g. {@link PixelFormat#RGBA5551 RGBA5551}
*/
boolean isUniform();
/**
* Returns {@code true} if all components are packed, i.e. interleaved, e.g. {@link PixelFormat#RGBA8888 RGBA8888},
* otherwise {@code false}.
*/
boolean isInterleaved();
/** Number of components per pixel, e.g. 3 for {@link PixelFormat#RGBx8888 RGBx8888}. */
int componentCount();
/** Number of bits per pixel, e.g. 24 bits for {@link PixelFormat#RGBx8888 RGBx8888}. */
int bitsPerPixel();
/**
* Bit distance between pixels.
*
* For packed pixels e.g. 32 bits for {@link PixelFormat#RGBx8888 RGBx8888}.
*
*/
int bitStride();
/** Number of bytes per pixel, i.e. packed {@link #bitStride()} in bytes, e.g. 4 for {@link PixelFormat#RGBx8888 RGBx8888}. */
int bytesPerPixel();
/**
* Returns the {@link CType Component type} order of all components, see {@link #componentBitMask()}.
*/
CType[] componentOrder();
/**
* Returns the index of given {@link CType} within {@link #componentOrder()}, -1 if not exists.
*/
int find(final PixelFormat.CType s);
/**
* Returns the un-shifted bit-mask of all components.
*
* Components mask is returned in the order Low-Index to High-Index, e.g.:
*
* - {@link PixelFormat#RGB565 RGB565}: 0: R 0x1F, 1: G 0x3F, 2: B 0x1F
* - {@link PixelFormat#RGBA5551 RGBA5551}: 0: R 0x1F, 1: G 0x1F, 2: B 0x1F, 3: A 0x01
* - {@link PixelFormat#RGBA8888 RGBA8888}: 0: R 0xFF, 1: G 0xFF, 2: B 0xFF, 3: A 0xFF
*
*
*
*/
int[] componentBitMask();
/**
* Returns the number of bits of all components, see {@link #componentBitMask()}.
*/
int[] componentBitCount();
/**
* Returns the bit-shift of all components, see {@link #componentBitMask()}.
*/
int[] componentBitShift();
/**
* Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 32bit.
* @param shifted complete pixel encoded into on 32bit integer
* @param cIdx the desired component index
* @return the decoded component value
*/
int decodeSingleI32(final int shifted, final int cIdx);
/**
* Decodes a component from the shifted pixel data with a {@link #bytesPerPixel()} of up to 64bit.
* @param shifted complete pixel encoded into on 64bit integer
* @param cIdx the desired component index
* @return the decoded component value
*/
int decodeSingleI64(final long shifted, final int cIdx);
int encodeSingleI32(final int norm, final int cIdx);
long encodeSingleI64(final int norm, final int cIdx);
int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32);
int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32);
int encodeSingleI8(final byte normalI8, final int cIdx);
int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8);
int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8);
float toFloat(final int i32, final int cIdx, final boolean i32Shifted);
int fromFloat(final float f, final int cIdx, final boolean shiftResult);
int defaultValue(final int cIdx, final boolean shiftResult);
/**
* Returns cached immutable hash value, see {@link Object#hashCode()}.
*/
int hashCode();
/**
* Returns {@link Object#equals(Object)}
*/
boolean equals(final Object o);
/**
* Returns {@link Object#toString()}.
*/
String toString();
}
/**
* Packed pixel composition, see {@link Composition}.
*
* Components are interleaved, i.e. packed.
*
*/
public static class PackedComposition implements Composition {
private final CType[] compOrder;
private final int[] compMask;
private final int[] compBitCount;
private final int[] compBitShift;
private final int bitsPerPixel;
private final int bitStride;
private final boolean uniform;
private final int hashCode;
public final String toString() {
return String.format("PackedComp[order %s, stride %d, bpp %d, uni %b, comp %d: %s]",
Arrays.toString(compOrder), bitStride, bitsPerPixel, uniform,
compMask.length, toHexString(compBitCount, compMask, compBitShift));
}
/**
* @param componentOrder {@link CType Component type} order of all components, see {@link #componentBitMask()}.
* @param componentCount number of components
* @param bpc bits per component
* @param bitStride stride bits to next pixel
*/
public PackedComposition(final CType[] componentOrder, final int componentCount, final int bpc, final int bitStride) {
this.compOrder = componentOrder;
this.compMask = new int[componentCount];
this.compBitShift = new int[componentCount];
this.compBitCount = new int[componentCount];
final int compMask = ( 1 << bpc ) - 1;
for(int i=0; i=0; i--) {
final int cmask = componentMask[i];
final int bitCount = Bitfield.Util.bitCount(cmask);
bpp += bitCount;
this.compBitCount[i] = bitCount;
if( i > 0 && uniform ) {
uniform = componentMask[i-1] == cmask;
}
}
this.uniform = uniform;
this.bitsPerPixel = bpp;
this.bitStride = bitStride;
if( this.bitStride < this.bitsPerPixel ) {
throw new IllegalArgumentException(String.format("bit-stride %d < bitsPerPixel %d", this.bitStride, this.bitsPerPixel));
}
this.hashCode = hashCodeImpl();
}
@Override
public final boolean isUniform() { return uniform; }
/**
* {@inheritDoc}
*
* Instances of {@link PackedComposition} returns {@code true}.
*
*/
@Override
public final boolean isInterleaved() { return true; }
@Override
public final int componentCount() { return compMask.length; }
@Override
public final int bitsPerPixel() { return bitsPerPixel; }
@Override
public final int bitStride() { return bitStride; }
@Override
public final int bytesPerPixel() { return (7+bitStride)/8; }
@Override
public final CType[] componentOrder() { return compOrder; }
@Override
public final int find(final PixelFormat.CType s) { return PixelFormatUtil.find(s, compOrder, false /* mapRGB2Y */); }
@Override
public final int[] componentBitMask() { return compMask; }
@Override
public final int[] componentBitCount() { return compBitCount; }
@Override
public final int[] componentBitShift() { return compBitShift; }
@Override
public final int decodeSingleI32(final int shifted, final int cIdx) {
return ( shifted >>> compBitShift[cIdx] ) & compMask[cIdx];
}
@Override
public final int decodeSingleI64(final long shifted, final int cIdx) {
return ( (int)( 0xffffffffL & ( shifted >>> compBitShift[cIdx] ) ) ) & compMask[cIdx];
}
@Override
public final int encodeSingleI32(final int norm, final int cIdx) {
return ( norm & compMask[cIdx] ) << compBitShift[cIdx] ;
}
@Override
public final long encodeSingleI64(final int norm, final int cIdx) {
return ( 0xffffffffL & ( norm & compMask[cIdx] ) ) << compBitShift[cIdx] ;
}
@Override
public final int encode3CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32) {
return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
( c2NormI32 & compMask[1] ) << compBitShift[1] |
( c3NormI32 & compMask[2] ) << compBitShift[2] ;
}
@Override
public final int encode4CompI32(final int c1NormI32, final int c2NormI32, final int c3NormI32, final int c4NormI32) {
return ( c1NormI32 & compMask[0] ) << compBitShift[0] |
( c2NormI32 & compMask[1] ) << compBitShift[1] |
( c3NormI32 & compMask[2] ) << compBitShift[2] |
( c4NormI32 & compMask[3] ) << compBitShift[3] ;
}
@Override
public final int encodeSingleI8(final byte normI8, final int cIdx) {
return ( normI8 & compMask[cIdx] ) << compBitShift[cIdx] ;
}
@Override
public final int encode3CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8) {
return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
( c2NormI8 & compMask[1] ) << compBitShift[1] |
( c3NormI8 & compMask[2] ) << compBitShift[2] ;
}
@Override
public final int encode4CompI8(final byte c1NormI8, final byte c2NormI8, final byte c3NormI8, final byte c4NormI8) {
return ( c1NormI8 & compMask[0] ) << compBitShift[0] |
( c2NormI8 & compMask[1] ) << compBitShift[1] |
( c3NormI8 & compMask[2] ) << compBitShift[2] |
( c4NormI8 & compMask[3] ) << compBitShift[3] ;
}
@Override
public final float toFloat(final int i32, final int cIdx, final boolean i32Shifted) {
if( i32Shifted ) {
return ( ( i32 >>> compBitShift[cIdx] ) & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
} else {
return ( i32 & compMask[cIdx] ) / (float)( compMask[cIdx] ) ;
}
}
@Override
public final int fromFloat(final float f, final int cIdx, final boolean shiftResult) {
final int v = (int)(f * compMask[cIdx] + 0.5f);
return shiftResult ? v << compBitShift[cIdx] : v;
}
@Override
public final int defaultValue(final int cIdx, final boolean shiftResult) {
final int v = ( CType.A == compOrder[cIdx] || CType.Y == compOrder[cIdx] )
? compMask[cIdx] : 0;
return shiftResult ? v << compBitShift[cIdx] : v;
}
@Override
public final int hashCode() { return hashCode; }
private final int hashCodeImpl() {
// 31 * x == (x << 5) - x
int hash = 31 + bitStride;
hash = ((hash << 5) - hash) + bitsPerPixel;
hash = ((hash << 5) - hash) + compMask.length;
for(int i=compOrder.length-1; i>=0; i--) {
hash = ((hash << 5) - hash) + compOrder[i].ordinal();
}
for(int i=compMask.length-1; i>=0; i--) {
hash = ((hash << 5) - hash) + compMask[i];
}
for(int i=compBitShift.length-1; i>=0; i--) {
hash = ((hash << 5) - hash) + compBitShift[i];
}
return hash;
}
@Override
public final boolean equals(final Object obj) {
if(this == obj) { return true; }
if( obj instanceof PackedComposition ) {
final PackedComposition other = (PackedComposition) obj;
return bitStride == other.bitStride &&
bitsPerPixel == other.bitsPerPixel &&
Arrays.equals(compOrder, other.compOrder) &&
Arrays.equals(compMask, other.compMask) &&
Arrays.equals(compBitShift, other.compBitShift);
} else {
return false;
}
}
}
private static String toHexString(final int[] bitCount, final int[] mask, final int[] shift) {
final StringBuilder sb = new StringBuilder();
sb.append("[");
final int l = mask.length;
for(int i=0; i < l; i++) {
if(i > 0) {
sb.append(", ");
}
sb.append(bitCount[i]).append(": ").
append("0x").append(Integer.toHexString(mask[i])).append(" << ").append(shift[i]);
}
return sb.append("]").toString();
}
}