Refactorings and code clean-up

This commit is contained in:
Harald Kuhr
2026-03-05 21:02:04 +01:00
parent a7a4445ce8
commit 7f2eb517ef
9 changed files with 65 additions and 58 deletions

View File

@@ -6,7 +6,7 @@ package com.twelvemonkeys.imageio.plugins.dds;
* <a href="https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#compression-algorithms">Compression Algorithms</a>
* <a href="https://github.com/microsoft/DirectXTK12/wiki/DDSTextureLoader#remarks">An extended Non-DX10 FourCC list</a>
*/
public enum DDSEncoderType {
enum DDSEncoderType {
BC1(DDSType.DXT1.value(), DDS.DXGI_FORMAT_BC1_UNORM, 8),
BC2(DDSType.DXT2.value(), DDS.DXGI_FORMAT_BC2_UNORM, 16),
BC3(DDSType.DXT5.value(), DDS.DXGI_FORMAT_BC3_UNORM, 16),
@@ -26,14 +26,6 @@ public enum DDSEncoderType {
rgbaMask = null;
}
//non-fourCC constructor (e.g. A8R8G8B8)
DDSEncoderType(int dx10DxgiFormat, int bitCount, int[] masks) {
fourCC = 0;
this.dx10DxgiFormat = dx10DxgiFormat;
bitCountOrBlockSize = bitCount;
rgbaMask = masks;
}
boolean isFourCC() {
return fourCC != 0;
}

View File

@@ -173,8 +173,14 @@ class DDSImageDataEncoder {
boolean getBlockEndpoints(int[] sampledColors, int[] paletteBuffer) {
if (sampledColors.length != 64)
throw new IllegalStateException("Unintended behaviour, expecting sampled colors of block to be 64, got " + sampledColors.length);
int minR = 0xff; int minG = 0xff; int minB = 0xff;
int maxR = 0; int maxG = 0; int maxB = 0;
int minR = 0xff;
int minG = 0xff;
int minB = 0xff;
int maxR = 0;
int maxG = 0;
int maxB = 0;
boolean alphaMode = false;
int i = 0;
while (i < 64) {
@@ -209,7 +215,6 @@ class DDSImageDataEncoder {
return alphaMode;
}
//Reference [3] Page 7
boolean getBlockEndpoints2(int[] sampled, int[] paletteBuffer) {
int maxDistance = -1;

View File

@@ -34,8 +34,8 @@ import com.twelvemonkeys.imageio.StandardImageMetadataSupport;
import javax.imageio.ImageTypeSpecifier;
final class DDSMetadata extends StandardImageMetadataSupport {
DDSMetadata(ImageTypeSpecifier type, DDSHeader header) {
final class DDSImageMetadata extends StandardImageMetadataSupport {
DDSImageMetadata(ImageTypeSpecifier type, DDSHeader header) {
super(builder(type)
.withCompressionTypeName(compressionName(header))
.withFormatVersion("1.0")

View File

@@ -146,7 +146,7 @@ public final class DDSImageReader extends ImageReaderBase {
public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
ImageTypeSpecifier imageType = getRawImageType(imageIndex);
return new DDSMetadata(imageType, header);
return new DDSImageMetadata(imageType, header);
}
private void readHeader() throws IOException {

View File

@@ -18,7 +18,8 @@ import java.nio.file.Files;
import java.nio.file.Paths;
/**
* A designated class to begin writing DDS file with headers, class {@link DDSImageDataEncoder} will handle image data encoding process
* A designated class to begin writing DDS file with headers,
* {@link DDSImageDataEncoder} will handle image data encoding process
*/
class DDSImageWriter extends ImageWriterBase {
protected DDSImageWriter(ImageWriterSpi provider) {
@@ -26,8 +27,8 @@ class DDSImageWriter extends ImageWriterBase {
}
@Override
public DDSWriterParam getDefaultWriteParam() {
return DDSWriterParam.DEFAULT_PARAM;
public DDSImageWriterParam getDefaultWriteParam() {
return DDSImageWriterParam.builder().formatBC5().build();
}
@Override
@@ -37,7 +38,8 @@ class DDSImageWriter extends ImageWriterBase {
ensureTextureSize(renderedImage);
ensureImageChannels(renderedImage);
DDSWriterParam ddsParam = param instanceof DDSWriterParam ? ((DDSWriterParam) param) : this.getDefaultWriteParam();
// TODO: Need to copy params from 'param' here in case of non-DDS param...
DDSImageWriterParam ddsParam = param instanceof DDSImageWriterParam ? ((DDSImageWriterParam) param) : getDefaultWriteParam();
processImageStarted(0);
imageOutput.setByteOrder(ByteOrder.BIG_ENDIAN);
@@ -59,7 +61,6 @@ class DDSImageWriter extends ImageWriterBase {
/**
* Checking if the image has 3 channels (RGB) or 4 channels (RGBA) and if image has 8 bits/channel.
*/
private void ensureImageChannels(RenderedImage renderedImage) {
Raster data = renderedImage.getData();
int numBands = data.getNumBands();
@@ -82,7 +83,7 @@ class DDSImageWriter extends ImageWriterBase {
}
private void writeHeader(IIOImage image, DDSWriterParam param) throws IOException {
private void writeHeader(IIOImage image, DDSImageWriterParam param) throws IOException {
imageOutput.writeInt(DDS.HEADER_SIZE);
imageOutput.writeInt(DDS.FLAG_CAPS | DDS.FLAG_HEIGHT | DDS.FLAG_WIDTH | DDS.FLAG_PIXELFORMAT | param.getOptionalBitFlags());
RenderedImage renderedImage = image.getRenderedImage();
@@ -109,14 +110,14 @@ class DDSImageWriter extends ImageWriterBase {
}
//https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dds-pixelformat
private void writePixelFormat(DDSWriterParam param) throws IOException {
private void writePixelFormat(DDSImageWriterParam param) throws IOException {
imageOutput.writeInt(DDS.DDSPF_SIZE);
writePixelFormatFlags(param);
writeFourCC(param);
writeRGBAData(param);
}
private void writeDXT10Header(DDSWriterParam param) throws IOException {
private void writeDXT10Header(DDSImageWriterParam param) throws IOException {
if (param.isUsingDxt10()) {
//dxgiFormat
imageOutput.writeInt(param.getDxgiFormat());
@@ -131,7 +132,7 @@ class DDSImageWriter extends ImageWriterBase {
}
}
private void writeRGBAData(DDSWriterParam param) throws IOException {
private void writeRGBAData(DDSImageWriterParam param) throws IOException {
if (!param.isUsingDxt10() && !param.getEncoderType().isFourCC()) {
//dwRGBBitCount
imageOutput.writeInt(param.getEncoderType().getBitsOrBlockSize());
@@ -151,7 +152,7 @@ class DDSImageWriter extends ImageWriterBase {
}
}
private void writeFourCC(DDSWriterParam param) throws IOException {
private void writeFourCC(DDSImageWriterParam param) throws IOException {
if (param.isUsingDxt10()) {
imageOutput.writeInt(DDSType.DXT10.value());
} else if (param.getEncoderType().isFourCC())
@@ -159,7 +160,7 @@ class DDSImageWriter extends ImageWriterBase {
}
private void writePixelFormatFlags(DDSWriterParam param) throws IOException {
private void writePixelFormatFlags(DDSImageWriterParam param) throws IOException {
if (param.isUsingDxt10() || param.getEncoderType().isFourCC()) {
imageOutput.writeInt(DDS.PIXEL_FORMAT_FLAG_FOURCC);
} else {
@@ -167,7 +168,7 @@ class DDSImageWriter extends ImageWriterBase {
}
}
private void writePitchOrLinearSize(int height, int width, DDSWriterParam param) throws IOException {
private void writePitchOrLinearSize(int height, int width, DDSImageWriterParam param) throws IOException {
DDSEncoderType type = param.getEncoderType();
int bitsOrBlockSize = type.getBitsOrBlockSize();
if (type.isBlockCompression()) {

View File

@@ -3,14 +3,21 @@ package com.twelvemonkeys.imageio.plugins.dds;
import javax.imageio.ImageWriteParam;
import java.util.Objects;
public class DDSWriterParam extends ImageWriteParam {
public static final DDSWriterParam DEFAULT_PARAM = DDSWriterParam.builder().formatBC5().build();
public final class DDSImageWriterParam extends ImageWriteParam {
// TODO: Rewrite to use more standard "compressionType":
// See metadata format for how to create compression name based on fourCC, we probably need to change that as well (?)
// At least they need to agree on what the compression names are... BC1, BC2, etc? DXT1, DXT2, etc?
// Extra bit flags etc, may be set using custom methods
private final int optionalBitFlags;
private final DDSEncoderType encoderType;
private final boolean enableDxt10;
DDSWriterParam(int optionalBitFlags, DDSEncoderType encoderType, boolean isUsingDxt10) {
DDSImageWriterParam(int optionalBitFlags, DDSEncoderType encoderType, boolean isUsingDxt10) {
super();
canWriteCompressed = true; // always compressed
this.optionalBitFlags = optionalBitFlags;
this.encoderType = encoderType;
this.enableDxt10 = isUsingDxt10;
@@ -43,7 +50,7 @@ public class DDSWriterParam extends ImageWriteParam {
private boolean isUsingDxt10;
public Builder() {
this.optionalBitFlag = 0;
optionalBitFlag = 0;
encoderType = null;
isUsingDxt10 = false;
}
@@ -115,9 +122,9 @@ public class DDSWriterParam extends ImageWriteParam {
return this;
}
public DDSWriterParam build() {
public DDSImageWriterParam build() {
Objects.requireNonNull(encoderType, "no DDS format specified.");
return new DDSWriterParam(optionalBitFlag, encoderType, isUsingDxt10);
return new DDSImageWriterParam(optionalBitFlag, encoderType, isUsingDxt10);
}
public enum DDSFlags {

View File

@@ -35,18 +35,16 @@ import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
final class DDSProviderInfo extends ReaderWriterProviderInfo {
DDSProviderInfo() {
super(
DDSProviderInfo.class,
new String[]{"DDS", "dds"},
new String[]{"dds"},
new String[]{"image/vnd-ms.dds"},
"com.twelvemonkeys.imageio.plugins.dds.DDSImageReader",
new String[]{"com.twelvemonkeys.imageio.plugins.dds.DDSImageReaderSpi"},
"com.twelvemonkeys.imageio.plugins.dds.DDSImageWriter",
new String[]{"com.twelvemonkeys.imageio.plugins.dds.DDSImageWriterSpi"},
false, null, null,
null, null, true,
null, null, null,
null
DDSProviderInfo.class,
new String[] { "DDS", "dds" },
new String[] { "dds" },
new String[] { "image/vnd-ms.dds" },
"com.twelvemonkeys.imageio.plugins.dds.DDSImageReader",
new String[] { "com.twelvemonkeys.imageio.plugins.dds.DDSImageReaderSpi" },
"com.twelvemonkeys.imageio.plugins.dds.DDSImageWriter",
new String[] { "com.twelvemonkeys.imageio.plugins.dds.DDSImageWriterSpi" },
false, null, null, null, null,
true, null, null, null, null
);
}
}

View File

@@ -4,7 +4,7 @@ import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
//https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dds-header-dxt10
public final class DX10Header {
final class DX10Header {
final DX10DXGIFormat dxgiFormat;
final int resourceDimension, miscFlag, arraySize, miscFlags2;

View File

@@ -59,7 +59,9 @@ import com.twelvemonkeys.io.FileUtil;
import com.twelvemonkeys.io.enc.DecoderStream;
import com.twelvemonkeys.io.enc.PackBitsDecoder;
import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.xml.XMLSerializer;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.imageio.IIOException;
@@ -69,6 +71,7 @@ import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.plugins.jpeg.JPEGImageReadParam;
import javax.imageio.spi.ImageReaderSpi;
@@ -2897,18 +2900,19 @@ public final class TIFFImageReader extends ImageReaderBase {
BufferedImage image = reader.read(imageNo, param);
System.err.println("Read time: " + (System.currentTimeMillis() - start) + " ms");
// IIOMetadata metadata = reader.getImageMetadata(imageNo);
// if (metadata != null) {
// if (metadata.getNativeMetadataFormatName() != null) {
// Node tree = metadata.getAsTree(metadata.getNativeMetadataFormatName());
// replaceBytesWithUndefined((IIOMetadataNode) tree);
// new XMLSerializer(System.out, "UTF-8").serialize(tree, false);
// }
// /*else*/
// if (metadata.isStandardMetadataFormatSupported()) {
// new XMLSerializer(System.out, "UTF-8").serialize(metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName), false);
// }
// }
IIOMetadata metadata = reader.getImageMetadata(imageNo);
if (metadata != null) {
if (metadata.getNativeMetadataFormatName() != null) {
Node tree = metadata.getAsTree(metadata.getNativeMetadataFormatName());
replaceBytesWithUndefined((IIOMetadataNode) tree);
new XMLSerializer(System.out, "UTF-8").serialize(tree, false);
}
/*else*/
if (metadata.isStandardMetadataFormatSupported()) {
new XMLSerializer(System.out, "UTF-8").serialize(metadata.getAsTree(
IIOMetadataFormatImpl.standardMetadataFormatName), false);
}
}
System.err.println("image: " + image);