mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-04-30 00:00:01 -04:00
Major ImageMetadata refactor for more consistent standard metadata support.
Fixes a few related bugs as a bonus.
This commit is contained in:
+21
-9
@@ -67,18 +67,28 @@ import com.twelvemonkeys.io.enc.Decoder;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.color.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Reader for Apple Mac Paint Picture (PICT) format.
|
||||
@@ -2611,7 +2621,9 @@ public final class PICTImageReader extends ImageReaderBase {
|
||||
return getYPtCoord(getPICTFrame().height);
|
||||
}
|
||||
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int pIndex) {
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
// TODO: The images look slightly different in Preview.. Could indicate the color space is wrong...
|
||||
return Collections.singletonList(
|
||||
ImageTypeSpecifiers.createPacked(
|
||||
@@ -2623,10 +2635,10 @@ public final class PICTImageReader extends ImageReaderBase {
|
||||
|
||||
@Override
|
||||
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
ImageTypeSpecifier rawType = getRawImageType(imageIndex);
|
||||
getPICTFrame(); // TODO: Would probably be better to use readPictHeader here, but it isn't cached
|
||||
|
||||
return new PICTMetadata(version, screenImageXRatio, screenImageYRatio);
|
||||
return new PICTMetadata(rawType, version, screenImageXRatio, screenImageYRatio);
|
||||
}
|
||||
|
||||
protected static void showIt(final BufferedImage pImage, final String pTitle) {
|
||||
|
||||
+40
-79
@@ -1,8 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
import com.twelvemonkeys.imageio.AbstractMetadata;
|
||||
import com.twelvemonkeys.imageio.StandardImageMetadataSupport;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
/**
|
||||
* PICTMetadata.
|
||||
@@ -11,82 +41,13 @@ import javax.imageio.metadata.IIOMetadataNode;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PICTMetadata.java,v 1.0 23/03/2021 haraldk Exp$
|
||||
*/
|
||||
public class PICTMetadata extends AbstractMetadata {
|
||||
|
||||
private final int version;
|
||||
private final double screenImageXRatio;
|
||||
private final double screenImageYRatio;
|
||||
|
||||
PICTMetadata(final int version, final double screenImageXRatio, final double screenImageYRatio) {
|
||||
this.version = version;
|
||||
this.screenImageXRatio = screenImageXRatio;
|
||||
this.screenImageYRatio = screenImageYRatio;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
|
||||
|
||||
IIOMetadataNode csType = new IIOMetadataNode("ColorSpaceType");
|
||||
chroma.appendChild(csType);
|
||||
csType.setAttribute("name", "RGB");
|
||||
|
||||
// NOTE: Channels in chroma node reflects channels in color model (see data node, for channels in data)
|
||||
IIOMetadataNode numChannels = new IIOMetadataNode("NumChannels");
|
||||
chroma.appendChild(numChannels);
|
||||
numChannels.setAttribute("value", "3");
|
||||
|
||||
IIOMetadataNode blackIsZero = new IIOMetadataNode("BlackIsZero");
|
||||
chroma.appendChild(blackIsZero);
|
||||
blackIsZero.setAttribute("value", "TRUE");
|
||||
|
||||
return chroma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardDimensionNode() {
|
||||
if (screenImageXRatio > 0.0d && screenImageYRatio > 0.0d) {
|
||||
IIOMetadataNode node = new IIOMetadataNode("Dimension");
|
||||
double ratio = screenImageXRatio / screenImageYRatio;
|
||||
IIOMetadataNode subNode = new IIOMetadataNode("PixelAspectRatio");
|
||||
subNode.setAttribute("value", "" + ratio);
|
||||
node.appendChild(subNode);
|
||||
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardDataNode() {
|
||||
IIOMetadataNode data = new IIOMetadataNode("Data");
|
||||
|
||||
// As this is a vector-ish format, with possibly multiple regions of pixel data, this makes no sense... :-P
|
||||
// This is, however, consistent with the getRawImageTyp/getImageTypes
|
||||
|
||||
IIOMetadataNode planarConfiguration = new IIOMetadataNode("PlanarConfiguration");
|
||||
planarConfiguration.setAttribute("value", "PixelInterleaved");
|
||||
data.appendChild(planarConfiguration);
|
||||
|
||||
IIOMetadataNode sampleFormat = new IIOMetadataNode("SampleFormat");
|
||||
sampleFormat.setAttribute("value", "UnsignedIntegral");
|
||||
data.appendChild(sampleFormat);
|
||||
|
||||
IIOMetadataNode bitsPerSample = new IIOMetadataNode("BitsPerSample");
|
||||
bitsPerSample.setAttribute("value", "32");
|
||||
data.appendChild(bitsPerSample);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardDocumentNode() {
|
||||
IIOMetadataNode document = new IIOMetadataNode("Document");
|
||||
|
||||
IIOMetadataNode formatVersion = new IIOMetadataNode("FormatVersion");
|
||||
document.appendChild(formatVersion);
|
||||
formatVersion.setAttribute("value", Integer.toString(version));
|
||||
|
||||
return document;
|
||||
final class PICTMetadata extends StandardImageMetadataSupport {
|
||||
PICTMetadata(final ImageTypeSpecifier type, final int version, final double screenImageXRatio, final double screenImageYRatio) {
|
||||
super(builder(type)
|
||||
.withPixelAspectRatio(screenImageXRatio > 0.0d && screenImageYRatio > 0.0d ? screenImageXRatio / screenImageYRatio : 1)
|
||||
.withFormatVersion(Integer.toString(version))
|
||||
);
|
||||
// As this is a vector-ish format, some of the data makes no sense... :-P
|
||||
// It is, however, consistent with the getRawImageTyp/getImageTypes
|
||||
}
|
||||
}
|
||||
|
||||
+32
-4
@@ -1,3 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pntg;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
@@ -34,7 +64,7 @@ public final class PNTGImageReader extends ImageReaderBase {
|
||||
private static final Set<ImageTypeSpecifier> IMAGE_TYPES =
|
||||
Collections.singleton(ImageTypeSpecifiers.createIndexed(new int[] {-1, 0}, false, -1, 1, DataBuffer.TYPE_BYTE));
|
||||
|
||||
protected PNTGImageReader(final ImageReaderSpi provider) {
|
||||
PNTGImageReader(final ImageReaderSpi provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
@@ -123,9 +153,7 @@ public final class PNTGImageReader extends ImageReaderBase {
|
||||
|
||||
@Override
|
||||
public IIOMetadata getImageMetadata(final int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
return new PNTGMetadata();
|
||||
return new PNTGMetadata(getRawImageType(imageIndex));
|
||||
}
|
||||
|
||||
private void readHeader() throws IOException {
|
||||
|
||||
+30
@@ -1,3 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pntg;
|
||||
|
||||
import com.twelvemonkeys.imageio.spi.ImageReaderSpiBase;
|
||||
|
||||
+38
-73
@@ -1,8 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.pntg;
|
||||
|
||||
import com.twelvemonkeys.imageio.AbstractMetadata;
|
||||
import com.twelvemonkeys.imageio.StandardImageMetadataSupport;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
/**
|
||||
* PNTGMetadata.
|
||||
@@ -11,76 +41,11 @@ import javax.imageio.metadata.IIOMetadataNode;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: PNTGMetadata.java,v 1.0 23/03/2021 haraldk Exp$
|
||||
*/
|
||||
public class PNTGMetadata extends AbstractMetadata {
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
|
||||
|
||||
IIOMetadataNode csType = new IIOMetadataNode("ColorSpaceType");
|
||||
chroma.appendChild(csType);
|
||||
csType.setAttribute("name", "GRAY");
|
||||
|
||||
// NOTE: Channels in chroma node reflects channels in color model (see data node, for channels in data)
|
||||
IIOMetadataNode numChannels = new IIOMetadataNode("NumChannels");
|
||||
chroma.appendChild(numChannels);
|
||||
numChannels.setAttribute("value", "1");
|
||||
|
||||
IIOMetadataNode blackIsZero = new IIOMetadataNode("BlackIsZero");
|
||||
chroma.appendChild(blackIsZero);
|
||||
blackIsZero.setAttribute("value", "FALSE");
|
||||
|
||||
return chroma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardCompressionNode() {
|
||||
IIOMetadataNode compressionNode = new IIOMetadataNode("Compression");
|
||||
|
||||
IIOMetadataNode compressionTypeName = new IIOMetadataNode("CompressionTypeName");
|
||||
compressionTypeName.setAttribute("value", "PackBits"); // RLE?
|
||||
compressionNode.appendChild(compressionTypeName);
|
||||
compressionNode.appendChild(new IIOMetadataNode("Lossless"));
|
||||
// "value" defaults to TRUE
|
||||
|
||||
return compressionNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardDataNode() {
|
||||
IIOMetadataNode data = new IIOMetadataNode("Data");
|
||||
|
||||
// PlanarConfiguration
|
||||
IIOMetadataNode planarConfiguration = new IIOMetadataNode("PlanarConfiguration");
|
||||
planarConfiguration.setAttribute("value", "PixelInterleaved");
|
||||
data.appendChild(planarConfiguration);
|
||||
|
||||
IIOMetadataNode sampleFormat = new IIOMetadataNode("SampleFormat");
|
||||
sampleFormat.setAttribute("value", "UnsignedIntegral");
|
||||
data.appendChild(sampleFormat);
|
||||
|
||||
IIOMetadataNode bitsPerSample = new IIOMetadataNode("BitsPerSample");
|
||||
bitsPerSample.setAttribute("value", "1");
|
||||
data.appendChild(bitsPerSample);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardDocumentNode() {
|
||||
IIOMetadataNode document = new IIOMetadataNode("Document");
|
||||
|
||||
IIOMetadataNode formatVersion = new IIOMetadataNode("FormatVersion");
|
||||
document.appendChild(formatVersion);
|
||||
formatVersion.setAttribute("value", "1.0");
|
||||
|
||||
// TODO: We could get the file creation time from MacBinary header here...
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardTextNode() {
|
||||
// TODO: We could get the file name from MacBinary header here...
|
||||
return super.getStandardTextNode();
|
||||
final class PNTGMetadata extends StandardImageMetadataSupport {
|
||||
public PNTGMetadata(ImageTypeSpecifier type) {
|
||||
super(builder(type)
|
||||
.withBlackIsZero(false)
|
||||
.withCompressionName("PackBits")
|
||||
.withFormatVersion("1.0"));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Harald Kuhr
|
||||
* Copyright (c) 2021, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
+5
-1
@@ -1,7 +1,11 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pntg;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* PNTGMetadataTest.
|
||||
*
|
||||
@@ -12,6 +16,6 @@ import org.junit.Test;
|
||||
public class PNTGMetadataTest {
|
||||
@Test
|
||||
public void testCreate() {
|
||||
new PNTGMetadata();
|
||||
new PNTGMetadata(ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_BINARY));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user