mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-10-03 23:53:15 -04:00
Use imageIndex to calculate height/width and buffer offset.
This commit is contained in:
@@ -2,18 +2,18 @@ package com.twelvemonkeys.imageio.plugins.dds;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.Dimension;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
|
||||
final class DDSHeader {
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dx-graphics-dds-pguide
|
||||
private int flags;
|
||||
private int width;
|
||||
private int height;
|
||||
private int mipmap;
|
||||
|
||||
private int mipMapCount;
|
||||
private Dimension[] dimensions;
|
||||
|
||||
private int pixelFormatFlags;
|
||||
private int fourCC;
|
||||
@@ -25,7 +25,7 @@ final class DDSHeader {
|
||||
|
||||
public static DDSHeader read(final ImageInputStream imageInput) throws IOException {
|
||||
DDSHeader header = new DDSHeader();
|
||||
|
||||
|
||||
// Read MAGIC bytes [0,3]
|
||||
byte[] magic = new byte[DDS.MAGIC.length];
|
||||
imageInput.readFully(magic);
|
||||
@@ -50,13 +50,15 @@ final class DDSHeader {
|
||||
}
|
||||
|
||||
// Read Height & Width
|
||||
header.height = imageInput.readInt(); // [12,15]
|
||||
header.width = imageInput.readInt(); // [16,19]
|
||||
|
||||
int dwHeight = imageInput.readInt(); // [12,15]
|
||||
int dwWidth = imageInput.readInt(); // [16,19]
|
||||
|
||||
int dwPitchOrLinearSize = imageInput.readInt(); // [20,23]
|
||||
int dwDepth = imageInput.readInt(); // [24,27]
|
||||
header.mipmap = imageInput.readInt(); // [28,31]
|
||||
header.mipMapCount = imageInput.readInt(); // [28,31]
|
||||
|
||||
// build dimensions list
|
||||
header.addDimensions(dwWidth, dwHeight);
|
||||
|
||||
byte[] dwReserved1 = new byte[11 * 4]; // [32,75]
|
||||
imageInput.readFully(dwReserved1);
|
||||
@@ -82,28 +84,35 @@ final class DDSHeader {
|
||||
return header;
|
||||
}
|
||||
|
||||
private void addDimensions(int width, int height) {
|
||||
dimensions = new Dimension[getMipMapCount()];
|
||||
|
||||
int w = width;
|
||||
int h = height;
|
||||
for (int i = 0; i < getMipMapCount(); i++) {
|
||||
dimensions[i] = new Dimension(w, h);
|
||||
w /= 2;
|
||||
h /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getFlag(int mask) {
|
||||
return (flags & mask) != 0;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
public int getWidth(int imageIndex) {
|
||||
int lim = dimensions[imageIndex].width;
|
||||
return (lim <= 0) ? 1 : lim;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
public int getHeight(int imageIndex) {
|
||||
int lim = dimensions[imageIndex].height;
|
||||
return (lim <= 0) ? 1 : lim;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getMipmap() {
|
||||
return mipmap;
|
||||
public int getMipMapCount() {
|
||||
// 0 = (unused) or 1 = (1 level), but still only one 'base' image
|
||||
return (mipMapCount == 0) ? 1 : mipMapCount;
|
||||
}
|
||||
|
||||
public int getAlphaMask() {
|
||||
|
@@ -34,7 +34,7 @@ public final class DDSImageReader extends ImageReaderBase {
|
||||
checkBounds(imageIndex);
|
||||
readHeader();
|
||||
|
||||
return header.getWidth();
|
||||
return header.getWidth(imageIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,7 +42,14 @@ public final class DDSImageReader extends ImageReaderBase {
|
||||
checkBounds(imageIndex);
|
||||
readHeader();
|
||||
|
||||
return header.getHeight();
|
||||
return header.getHeight(imageIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumImages(final boolean allowSearch) throws IOException {
|
||||
readHeader();
|
||||
|
||||
return header.getMipMapCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -29,39 +29,21 @@ final class DDSReader {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public int[] read(ImageInputStream imageInput, int mipmapLevel) throws IOException {
|
||||
|
||||
// header
|
||||
int width = header.getWidth();
|
||||
int height = header.getHeight();
|
||||
int mipmap = header.getMipmap();
|
||||
|
||||
if (mipmapLevel > mipmap) {
|
||||
throw new IIOException("Invalid mipmap level: " + mipmapLevel);
|
||||
}
|
||||
public int[] read(ImageInputStream imageInput, int imageIndex) throws IOException {
|
||||
|
||||
// type
|
||||
DDSType type = getType();
|
||||
|
||||
// length
|
||||
int len = getLength(type, width, height);
|
||||
byte[] buffer = new byte[len];
|
||||
imageInput.readFully(buffer);
|
||||
|
||||
for (int i = 1; i < mipmapLevel; i++) {
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
// length
|
||||
len = getLength(type, width, height);
|
||||
// offset buffer to index mipmap image
|
||||
byte[] buffer = null;
|
||||
for (int i = 0; i <= imageIndex; i++) {
|
||||
int len = getLength(type, i);
|
||||
buffer = new byte[len];
|
||||
imageInput.readFully(buffer);
|
||||
}
|
||||
if (width <= 0) width = 1;
|
||||
if (height <= 0) height = 1;
|
||||
|
||||
header.setWidth(width);
|
||||
header.setHeight(height);
|
||||
int width = header.getWidth(imageIndex);
|
||||
int height = header.getHeight(imageIndex);
|
||||
|
||||
switch (type) {
|
||||
case DXT1:
|
||||
@@ -163,7 +145,10 @@ final class DDSReader {
|
||||
}
|
||||
}
|
||||
|
||||
private static int getLength(DDSType type, int width, int height) throws IIOException {
|
||||
private int getLength(DDSType type, int imageIndex) throws IIOException {
|
||||
int width = header.getWidth(imageIndex);
|
||||
int height = header.getHeight(imageIndex);
|
||||
|
||||
switch (type) {
|
||||
case DXT1:
|
||||
return 8 * ((width + 3) / 4) * ((height + 3) / 4);
|
||||
|
Reference in New Issue
Block a user