📄 ddsloader.java
字号:
} else if (pitchOrSize_ != size) {
logger.warning("Expected size = " + size + ", real = " + pitchOrSize_);
}
} else {
pitchOrSize_ = size;
}
}
}
/**
* Computes the sizes of each mipmap level in bytes, and stores it in sizes_[].
*/
private void loadSizes() {
int width = width_;
int height = height_;
sizes_ = new int[mipMapCount_];
for (int i = 0; i < mipMapCount_; i++) {
int size;
if (compressed_) {
size = ((width + 3) / 4) * ((height + 3) / 4) * bpp_ * 2;
} else {
size = width * height * bpp_ / 8;
}
sizes_[i] = ((size + 3) / 4) * 4;
width = Math.max(width / 2, 1);
height = Math.max(height / 2, 1);
}
}
/**
* Flips the given image data on the Y axis.
* @param data Data array containing image data (without mipmaps)
* @param scanlineSize Size of a single scanline = width * bytesPerPixel
* @param height Height of the image in pixels
* @return The new data flipped by the Y axis
*/
public byte[] flipData(byte[] data, int scanlineSize, int height){
byte[] newData = new byte[data.length];
for (int y = 0; y < height; y++){
System.arraycopy(data, y * scanlineSize,
newData, (height-y-1) * scanlineSize,
scanlineSize);
}
return newData;
}
/**
* Reads a grayscale image with mipmaps from the InputStream
* @param flip Flip the loaded image by Y axis
* @param totalSize Total size of the image in bytes including the mipmaps
* @return A ByteBuffer containing the grayscale image data with mips.
* @throws java.io.IOException If an error occured while reading from InputStream
*/
public ByteBuffer readGrayscale2D(boolean flip, int totalSize) throws IOException{
ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize);
if (bpp_ == 8)
logger.finest("Source image format: R8");
assert bpp_ / 8 == Image.getEstimatedByteSize(pixelFormat_);
int width = width_;
int height = height_;
for (int mip = 0; mip < mipMapCount_; mip++){
byte[] data = new byte[sizes_[mip]];
in_.readFully(data);
if (flip) data = flipData(data, width * bpp_ / 8, height);
buffer.put(data);
width = Math.max(width / 2, 1);
height = Math.max(height / 2, 1);
}
return buffer;
}
/**
* Reads an uncompressed RGB or RGBA image.
*
* @param flip Flip the image on the Y axis
* @param totalSize Size of the image in bytes including mipmaps
* @return ByteBuffer containing image data with mipmaps in the format specified by pixelFormat_
* @throws java.io.IOException If an error occured while reading from InputStream
*/
public ByteBuffer readRGB2D(boolean flip, int totalSize) throws IOException{
int redCount = count(redMask_),
blueCount = count(blueMask_),
greenCount = count(greenMask_),
alphaCount = count(alphaMask_);
if (redMask_ == 0x00FF0000
&& greenMask_ == 0x0000FF00
&& blueMask_ == 0x000000FF){
if (alphaMask_ == 0xFF000000 && bpp_ == 32){
logger.finest("Data source format: BGRA8");
}else if (bpp_ == 24){
logger.finest("Data source format: BGR8");
}
}
int sourcebytesPP = bpp_ / 8;
int targetBytesPP = Image.getEstimatedByteSize(pixelFormat_);
ByteBuffer dataBuffer = BufferUtils.createByteBuffer(totalSize);
int width = width_;
int height = height_;
int offset = 0;
for (int mip = 0; mip < mipMapCount_; mip++){
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
byte[] b = new byte[sourcebytesPP];
in_.readFully(b);
int i = byte2int(b);
byte red = (byte) (((i & redMask_) >> redCount));
byte green = (byte) (((i & greenMask_) >> greenCount));
byte blue = (byte) (((i & blueMask_) >> blueCount));
byte alpha = (byte) (((i & alphaMask_) >> alphaCount));
if (flip)
dataBuffer.position(offset + ((height-y-1) * width + x) * targetBytesPP);
//else
// dataBuffer.position(offset + (y * width + x) * targetBytesPP);
if (alphaMask_ == 0){
dataBuffer.put(red).put(green).put(blue);
}else{
dataBuffer.put(red).put(green).put(blue).put(alpha);
}
}
}
offset += width * height * targetBytesPP;
width = Math.max(width / 2, 1);
height = Math.max(height / 2, 1);
}
return dataBuffer;
}
/**
* Reads a DXT compressed image from the InputStream
*
* @param totalSize Total size of the image in bytes, including mipmaps
* @return ByteBuffer containing compressed DXT image in the format specified by pixelFormat_
* @throws java.io.IOException If an error occured while reading from InputStream
*/
public ByteBuffer readDXT2D(int totalSize) throws IOException{
byte[] data = new byte[totalSize];
in_.readFully(data);
logger.finest("Source image format: DXT");
ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize);
buffer.put(data);
buffer.rewind();
return buffer;
}
/**
* Reads the image data from the InputStream in the required format.
* If the file contains a cubemap image, it is loaded as 6 ByteBuffers
* (potentially containing mipmaps if they were specified), otherwise
* a single ByteBuffer is returned for a 2D image.
*
* @param flip Flip the image data or not.
* For cubemaps, each of the cubemap faces is flipped individually.
* If the image is DXT compressed, no flipping is done.
* @return An ArrayList containing a single ByteBuffer for a 2D image, or 6 ByteBuffers for a cubemap.
* The cubemap ByteBuffer order is PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ.
*
* @throws java.io.IOException If an error occured while reading from the stream.
*/
public ArrayList<ByteBuffer> readData(boolean flip) throws IOException {
int totalSize = 0;
for (int i = 0; i < sizes_.length; i++) {
totalSize += sizes_[i];
}
ArrayList<ByteBuffer> allMaps = new ArrayList<ByteBuffer>();
if (is(caps2_, DDSCAPS2_CUBEMAP)) {
for (int i = 0; i < 6; i++){
if (compressed_){
allMaps.add( readDXT2D(totalSize));
}else if (grayscaleOrAlpha_){
allMaps.add( readGrayscale2D(flip, totalSize));
}else{
allMaps.add( readRGB2D(flip, totalSize));
}
}
}else{
if (compressed_){
allMaps.add( readDXT2D(totalSize));
}else if (grayscaleOrAlpha_){
allMaps.add( readGrayscale2D(flip, totalSize));
}else{
allMaps.add( readRGB2D(flip, totalSize));
}
}
return allMaps;
}
/**
* Checks if flags contains the specified mask
*/
private static final boolean is(int flags, int mask) {
return (flags & mask) == mask;
}
/**
* Counts the amount of bits needed to shift till bitmask n is at zero
* @param n Bitmask to test
*/
private static int count(int n) {
if (n == 0)
return 0;
int i = 0;
while ((n & 0x1) == 0) {
n = n >> 1;
i++;
if (i > 32)
throw new RuntimeException(Integer.toHexString(n));
}
return i;
}
/**
* Converts a 1 to 4 sized byte array to an integer
*/
private static int byte2int(byte[] b){
if (b.length == 1)
return b[0] & 0xFF;
else if (b.length == 2)
return (b[0] & 0xFF)
| ((b[1] & 0xFF) << 8);
else if (b.length == 3)
return (b[0] & 0xFF)
| ((b[1] & 0xFF) << 8)
| ((b[2] & 0xFF) << 16);
else if (b.length == 4)
return (b[0] & 0xFF)
| ((b[1] & 0xFF) << 8)
| ((b[2] & 0xFF) << 16)
| ((b[3] & 0xFF) << 24);
else
return 0;
}
/**
* Converts a int representing a FourCC into a String
*/
private static final String string(int value) {
StringBuffer buf = new StringBuffer();
buf.append((char) (value & 0xFF));
buf.append((char) ((value & 0xFF00) >> 8));
buf.append((char) ((value & 0xFF0000) >> 16));
buf.append((char) ((value & 0xFF00000) >> 24));
return buf.toString();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -