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