Merge branch 'master' of https://github.com/haraldk/TwelveMonkeys into tiffreader_eof

This commit is contained in:
Oliver Schmidtmer 2016-02-17 22:40:46 +01:00
commit ae548557bc
10 changed files with 143 additions and 13 deletions

View File

@ -100,7 +100,8 @@ public final class ColorSpaces {
*
* @param profile the ICC color profile. May not be {@code null}.
* @return an ICC color space
* @throws IllegalArgumentException if {@code profile} is {@code null}
* @throws IllegalArgumentException if {@code profile} is {@code null}.
* @throws java.awt.color.CMMException if {@code profile} is invalid.
*/
public static ICC_ColorSpace createColorSpace(final ICC_Profile profile) {
Validate.notNull(profile, "profile");

View File

@ -51,6 +51,7 @@ interface PSD {
/** PSD Resource type identifier "8BIM" */
int RESOURCE_TYPE = ('8' << 24) + ('B' << 16) + ('I' << 8) + 'M';
int RESOURCE_TYPE_LONG = ('8' << 24) + ('B' << 16) + ('6' << 8) + '4';;
// Blending modes
/** Pass through blending mode "pass"*/
@ -689,4 +690,22 @@ interface PSD {
/** Plug-In resource(s). Resources added by a plug-in. See the plug-in API found in the SDK documentation */
int RES_PLUGIN_MAX = 0x1387;
// TODO: Better naming of these.. It's a kind of resource blocks as well..
// "Additional Layer Information"
int LMsk = 'L' << 24 | 'M' << 16 | 's' << 8 | 'k';
int Lr16 = 'L' << 24 | 'r' << 16 | '1' << 8 | '6';
int Lr32 = 'L' << 24 | 'r' << 16 | '3' << 8 | '2';
int Layr = 'L' << 24 | 'a' << 16 | 'y' << 8 | 'r';
int Mt16 = 'M' << 24 | 't' << 16 | '1' << 8 | '6';
int Mt32 = 'M' << 24 | 't' << 16 | '3' << 8 | '2';
int Mtrn = 'M' << 24 | 't' << 16 | 'r' << 8 | 'n';
int Alph = 'A' << 24 | 'l' << 16 | 'p' << 8 | 'h';
int FMsk = 'F' << 24 | 'M' << 16 | 's' << 8 | 'k';
int lnk2 = 'l' << 24 | 'n' << 16 | 'k' << 8 | '2';
int FEid = 'F' << 24 | 'E' << 16 | 'i' << 8 | 'd';
int FXid = 'F' << 24 | 'X' << 16 | 'i' << 8 | 'd';
int PxSD = 'P' << 24 | 'x' << 16 | 'S' << 8 | 'D';
int luni = 'l' << 24 | 'u' << 16 | 'n' << 8 | 'i';
int lyid = 'l' << 24 | 'y' << 16 | 'i' << 8 | 'd';
}

View File

@ -50,7 +50,10 @@ final class PSDLayerInfo {
final PSDLayerBlendMode blendMode;
final PSDLayerMaskData layerMaskData;
final PSDChannelSourceDestinationRange[] ranges;
final String layerName;
private final String layerName;
private String unicodeLayerName;
private int layerId;
PSDLayerInfo(final boolean largeFormat, final ImageInputStream pInput) throws IOException {
top = pInput.readInt();
@ -70,7 +73,7 @@ final class PSDLayerInfo {
blendMode = new PSDLayerBlendMode(pInput);
// Length of layer mask data
// Length of layer extra data
long extraDataSize = pInput.readUnsignedInt();
// Layer mask/adjustment layer data
@ -92,19 +95,78 @@ final class PSDLayerInfo {
ranges[i] = new PSDChannelSourceDestinationRange(pInput, (i == 0 ? "Gray" : "Channel " + (i - 1)));
}
// Layer name
layerName = PSDUtil.readPascalString(pInput);
int layerNameSize = layerName.length() + 1;
// Skip pad bytes for long word alignment
if (layerNameSize % 4 != 0) {
int skip = layerNameSize % 4;
int skip = 4 - (layerNameSize % 4);
pInput.skipBytes(skip);
layerNameSize += skip;
}
// TODO: Consider reading this: Adjustment layer info etc...
pInput.skipBytes(extraDataSize - layerMaskDataSize - 4 - layerBlendingDataSize - 4 - layerNameSize);
// Parse "Additional layer data"
long additionalLayerInfoStart = pInput.getStreamPosition();
long expectedEnd = additionalLayerInfoStart + extraDataSize - layerMaskDataSize - 4 - layerBlendingDataSize - 4 - layerNameSize;
while (pInput.getStreamPosition() < expectedEnd) {
// 8BIM or 8B64
int resourceSignature = pInput.readInt();
if (resourceSignature != PSD.RESOURCE_TYPE && resourceSignature != PSD.RESOURCE_TYPE_LONG) {
// Could be a corrupt document, or some new resource (type) we don't know about,
// we'll just leave it and carry on, as this is all secondary information for the reader.
break;
}
int resourceKey = pInput.readInt();
// NOTE: Only SOME resources have long length fields...
boolean largeResource = resourceSignature != PSD.RESOURCE_TYPE;
long resourceLength = largeResource ? pInput.readLong() : pInput.readUnsignedInt();
long resourceStart = pInput.getStreamPosition();
// System.out.printf("signature: %s 0x%08x\n", PSDUtil.intToStr(resourceSignature), resourceSignature);
// System.out.println("key: " + PSDUtil.intToStr(resourceKey));
// System.out.println("length: " + resourceLength);
switch (resourceKey) {
case PSD.luni:
unicodeLayerName = PSDUtil.readUnicodeString(pInput);
// There's usually a 0-pad here, but it is skipped in the general re-aligning code below
break;
case PSD.lyid:
if (resourceLength != 4) {
throw new IIOException(String.format("Expected layerId length == 4: %d", resourceLength));
}
layerId = pInput.readInt();
break;
default:
// TODO: Parse more data...
pInput.skipBytes(resourceLength);
break;
}
// Re-align in case we got the length incorrect
if (pInput.getStreamPosition() != resourceStart + resourceLength) {
pInput.seek(resourceStart + resourceLength);
}
}
// Re-align in case we got the length incorrect
if (pInput.getStreamPosition() != expectedEnd) {
pInput.seek(expectedEnd);
}
}
String getLayerName() {
return unicodeLayerName != null ? unicodeLayerName : layerName;
}
int getLayerId() {
return layerId;
}
@Override
@ -122,7 +184,7 @@ final class PSDLayerInfo {
builder.append(", layer mask data: ").append(layerMaskData);
}
builder.append(", ranges: ").append(Arrays.toString(ranges));
builder.append(", layer name: \"").append(layerName).append("\"");
builder.append(", layer name: \"").append(getLayerName()).append("\"");
builder.append("]");
return builder.toString();

View File

@ -375,7 +375,7 @@ public final class PSDMetadata extends AbstractMetadata {
for (PSDLayerInfo psdLayerInfo : layerInfo) {
// TODO: Group in layer and use sub node for blend mode?
node = new IIOMetadataNode("LayerInfo");
node.setAttribute("name", psdLayerInfo.layerName);
node.setAttribute("name", psdLayerInfo.getLayerName());
node.setAttribute("top", String.valueOf(psdLayerInfo.top));
node.setAttribute("left", String.valueOf(psdLayerInfo.left));
node.setAttribute("bottom", String.valueOf(psdLayerInfo.bottom));

View File

@ -31,11 +31,16 @@ package com.twelvemonkeys.imageio.plugins.psd;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
import org.junit.Test;
import org.w3c.dom.NodeList;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
@ -385,4 +390,20 @@ public class PSDImageReaderTest extends ImageReaderAbstractTest<PSDImageReader>
}
}
}
@Test
public void testReadUnicodeLayerName() throws IOException {
PSDImageReader imageReader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/psd/long-layer-names.psd"))) {
imageReader.setInput(stream);
IIOMetadata metadata = imageReader.getImageMetadata(0);
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
NodeList layerInfo = root.getElementsByTagName("LayerInfo");
assertEquals(1, layerInfo.getLength()); // Sanity
assertEquals("If_The_Layer_Name_Is_Really_Long_Oh_No_What_Do_I_Do", ((IIOMetadataNode) layerInfo.item(0)).getAttribute("name"));
}
}
}

View File

@ -62,7 +62,7 @@ import java.util.SortedSet;
* @see com.twelvemonkeys.io.ole2.CompoundDocument
* @see <a href="http://en.wikipedia.org/wiki/Thumbs.db>Wikipedia: Thumbs.db</a>
*/
public class ThumbsDBImageReader extends ImageReaderBase {
public final class ThumbsDBImageReader extends ImageReaderBase {
private static final int THUMBNAIL_OFFSET = 12;
private Entry root;
private Catalog catalog;

View File

@ -47,7 +47,7 @@ import java.util.Locale;
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: ThumbsDBImageReaderSpi.java,v 1.0 28.feb.2006 19:21:05 haku Exp$
*/
public class ThumbsDBImageReaderSpi extends ImageReaderSpiBase {
public final class ThumbsDBImageReaderSpi extends ImageReaderSpiBase {
private ImageReaderSpi jpegProvider;
/**
@ -61,7 +61,7 @@ public class ThumbsDBImageReaderSpi extends ImageReaderSpiBase {
return source instanceof ImageInputStream && canDecode((ImageInputStream) source);
}
public boolean canDecode(final ImageInputStream pInput) throws IOException {
boolean canDecode(final ImageInputStream pInput) throws IOException {
maybeInitJPEGProvider();
// If this is a OLE 2 CompoundDocument, we could try...
// TODO: How do we know it's thumbs.db format (structure), without reading quite a lot?

View File

@ -314,7 +314,7 @@ public class TIFFImageReader extends ImageReaderBase {
readIFD(imageIndex);
int sampleFormat = getSampleFormat();
int planarConfiguration = getValueAsIntWithDefault(TIFF.TAG_PLANAR_CONFIGURATION, TIFFExtension.PLANARCONFIG_PLANAR);
int planarConfiguration = getValueAsIntWithDefault(TIFF.TAG_PLANAR_CONFIGURATION, TIFFBaseline.PLANARCONFIG_CHUNKY);
int interpretation = getValueAsInt(TIFF.TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation");
int samplesPerPixel = getValueAsIntWithDefault(TIFF.TAG_SAMPLES_PER_PIXEL, 1);
int bitsPerSample = getBitsPerSample();

27
pom.xml
View File

@ -12,6 +12,14 @@
<packaging>pom</packaging>
<name>Twelvemonkeys</name>
<licenses>
<license>
<name>The BSD License</name>
<url>https://github.com/haraldk/TwelveMonkeys#license</url>
<distribution>repo</distribution>
</license>
</licenses>
<modules>
<module>common</module>
<module>servlet</module>
@ -43,8 +51,27 @@
<role>maven-guru</role>
</roles>
</contributor>
<contributor>
<name>Oliver Schmidtmer</name>
<email>mail@trek7891.de</email>
<roles>
<role>contributor</role>
</roles>
</contributor>
<contributor>
<name>Jason Palmer</name>
<email>jpalmer@itemmaster.com</email>
<roles>
<role>contributor</role>
</roles>
</contributor>
</contributors>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/haraldk/TwelveMonkeys/issues</url>
</issueManagement>
<scm>
<connection>scm:git:https://github.com/haraldk/TwelveMonkeys</connection>
<developerConnection>scm:git:https://github.com/haraldk/TwelveMonkeys</developerConnection>