mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 20:15:28 -04:00
TMI-134: Cannot read PSD images with PSD Layer Mask data size 28
This commit is contained in:
parent
1a8948ece9
commit
9b71a0cba7
@ -74,7 +74,7 @@ final class PSDLayerInfo {
|
|||||||
long extraDataSize = pInput.readUnsignedInt();
|
long extraDataSize = pInput.readUnsignedInt();
|
||||||
|
|
||||||
// Layer mask/adjustment layer data
|
// Layer mask/adjustment layer data
|
||||||
int layerMaskDataSize = pInput.readInt(); // May be 0, 20 or 36 bytes...
|
int layerMaskDataSize = pInput.readInt(); // May be 0, 20 or variable (up to 55) bytes...
|
||||||
if (layerMaskDataSize != 0) {
|
if (layerMaskDataSize != 0) {
|
||||||
layerMaskData = new PSDLayerMaskData(pInput, layerMaskDataSize);
|
layerMaskData = new PSDLayerMaskData(pInput, layerMaskDataSize);
|
||||||
}
|
}
|
||||||
|
@ -47,42 +47,90 @@ final class PSDLayerMaskData {
|
|||||||
private int defaultColor;
|
private int defaultColor;
|
||||||
private int flags;
|
private int flags;
|
||||||
|
|
||||||
private boolean large;
|
private int maskParams;
|
||||||
private int realFlags;
|
private int userMaskDensity;
|
||||||
private int realUserBackground;
|
private double userMaskFeather;
|
||||||
private int realTop;
|
private int vectorMaskDensity;
|
||||||
private int realLeft;
|
private double vectorMaskFeather;
|
||||||
private int realBottom;
|
|
||||||
private int realRight;
|
|
||||||
|
|
||||||
PSDLayerMaskData(final ImageInputStream pInput, final int pSize) throws IOException {
|
PSDLayerMaskData(final ImageInputStream pInput, final int pSize) throws IOException {
|
||||||
if (pSize != 20 && pSize != 36) {
|
if (pSize < 20 || pSize > 55) {
|
||||||
throw new IIOException("Illegal PSD Layer Mask data size: " + pSize + " (expected 20 or 36)");
|
throw new IIOException("Illegal PSD Layer Mask data size: " + pSize + " (expected between 20 and 55)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rectangle enclosing layer mask: Top, left, bottom, right.
|
||||||
top = pInput.readInt();
|
top = pInput.readInt();
|
||||||
left = pInput.readInt();
|
left = pInput.readInt();
|
||||||
bottom = pInput.readInt();
|
bottom = pInput.readInt();
|
||||||
right = pInput.readInt();
|
right = pInput.readInt();
|
||||||
|
|
||||||
|
// Default color. 0 or 255
|
||||||
defaultColor = pInput.readUnsignedByte();
|
defaultColor = pInput.readUnsignedByte();
|
||||||
|
|
||||||
|
// Flags.
|
||||||
|
// bit 0 = position relative to layer
|
||||||
|
// bit 1 = layer mask disabled
|
||||||
|
// bit 2 = invert layer mask when blending (Obsolete)
|
||||||
|
// bit 3 = indicates that the user mask actually came from rendering other data
|
||||||
|
// bit 4 = indicates that the user and/or vector masks have parameters applied to them
|
||||||
flags = pInput.readUnsignedByte();
|
flags = pInput.readUnsignedByte();
|
||||||
|
|
||||||
if (pSize == 20) {
|
int dataLeft = pSize - 18;
|
||||||
|
|
||||||
|
if ((flags & 0x10) != 0) {
|
||||||
|
// Mask Parameters. Only present if bit 4 of Flags set above.
|
||||||
|
maskParams = pInput.readUnsignedByte();
|
||||||
|
dataLeft--;
|
||||||
|
|
||||||
|
// Mask Parameters bit flags present as follows:
|
||||||
|
// bit 0 = user mask density, 1 byte
|
||||||
|
// bit 1 = user mask feather, 8 byte, double
|
||||||
|
// bit 2 = vector mask density, 1 byte
|
||||||
|
// bit 3 = vector mask feather, 8 bytes, double
|
||||||
|
if ((maskParams & 0x01) != 0) {
|
||||||
|
userMaskDensity = pInput.readByte();
|
||||||
|
dataLeft--;
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x02) != 0) {
|
||||||
|
userMaskFeather = pInput.readDouble();
|
||||||
|
dataLeft -= 8;
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x04) != 0) {
|
||||||
|
vectorMaskDensity = pInput.readByte();
|
||||||
|
dataLeft--;
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x08) != 0) {
|
||||||
|
vectorMaskFeather = pInput.readDouble();
|
||||||
|
dataLeft -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Padding. Only present if size = 20. Otherwise the following is present
|
||||||
|
if (pSize == 20 && dataLeft == 2) {
|
||||||
pInput.readShort(); // Pad
|
pInput.readShort(); // Pad
|
||||||
|
dataLeft -= 2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: What to make out of this?
|
if (dataLeft >= 2) {
|
||||||
large = true;
|
// Real Flags. Same as Flags information above.
|
||||||
|
flags = pInput.readUnsignedByte();
|
||||||
|
dataLeft--;
|
||||||
|
// Real user mask background. 0 or 255.
|
||||||
|
defaultColor = pInput.readUnsignedByte();
|
||||||
|
dataLeft--;
|
||||||
|
}
|
||||||
|
if (dataLeft >= 16) {
|
||||||
|
// Rectangle enclosing layer mask: Top, left, bottom, right.
|
||||||
|
top = pInput.readInt();
|
||||||
|
left = pInput.readInt();
|
||||||
|
bottom = pInput.readInt();
|
||||||
|
right = pInput.readInt();
|
||||||
|
dataLeft -= 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
realFlags = pInput.readUnsignedByte();
|
if (dataLeft > 0) {
|
||||||
realUserBackground = pInput.readUnsignedByte();
|
pInput.skipBytes(dataLeft);
|
||||||
|
|
||||||
realTop = pInput.readInt();
|
|
||||||
realLeft = pInput.readInt();
|
|
||||||
realBottom = pInput.readInt();
|
|
||||||
realRight = pInput.readInt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,40 +145,54 @@ final class PSDLayerMaskData {
|
|||||||
builder.append(", default color: ").append(defaultColor);
|
builder.append(", default color: ").append(defaultColor);
|
||||||
builder.append(", flags: ").append(Integer.toBinaryString(flags));
|
builder.append(", flags: ").append(Integer.toBinaryString(flags));
|
||||||
|
|
||||||
// TODO: Maybe the flag bits have oposite order?
|
|
||||||
builder.append(" (");
|
builder.append(" (");
|
||||||
if ((flags & 0x01) != 0) {
|
if ((flags & 0x01) != 0) {
|
||||||
builder.append("Pos. rel. to layer");
|
builder.append("relative");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
builder.append("Pos. abs.");
|
builder.append("absolute");
|
||||||
}
|
}
|
||||||
if ((flags & 0x02) != 0) {
|
if ((flags & 0x02) != 0) {
|
||||||
builder.append(", Mask disabled");
|
builder.append(", disabled");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
builder.append(", Mask enabled");
|
builder.append(", enabled");
|
||||||
}
|
}
|
||||||
if ((flags & 0x04) != 0) {
|
if ((flags & 0x04) != 0) {
|
||||||
builder.append(", Invert mask");
|
builder.append(", inverted");
|
||||||
}
|
}
|
||||||
if ((flags & 0x08) != 0) {
|
if ((flags & 0x08) != 0) {
|
||||||
builder.append(", Unknown bit 3");
|
builder.append(", from rendered data");
|
||||||
}
|
}
|
||||||
if ((flags & 0x10) != 0) {
|
if ((flags & 0x10) != 0) {
|
||||||
builder.append(", Unknown bit 4");
|
builder.append(", has parameters");
|
||||||
}
|
}
|
||||||
if ((flags & 0x20) != 0) {
|
if ((flags & 0x20) != 0) {
|
||||||
builder.append(", Unknown bit 5");
|
builder.append(", unknown flag (bit 5)");
|
||||||
}
|
}
|
||||||
if ((flags & 0x40) != 0) {
|
if ((flags & 0x40) != 0) {
|
||||||
builder.append(", Unknown bit 6");
|
builder.append(", unknown flag (bit 6)");
|
||||||
}
|
}
|
||||||
if ((flags & 0x80) != 0) {
|
if ((flags & 0x80) != 0) {
|
||||||
builder.append(", Unknown bit 7");
|
builder.append(", unknown flag (bit 7)");
|
||||||
}
|
}
|
||||||
builder.append(")");
|
builder.append(")");
|
||||||
|
|
||||||
|
if ((flags & 0x10) != 0) {
|
||||||
|
if ((maskParams & 0x01) != 0) {
|
||||||
|
builder.append(", userMaskDensity: ").append(userMaskDensity);
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x02) != 0) {
|
||||||
|
builder.append(", userMaskFeather: ").append(userMaskFeather);
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x04) != 0) {
|
||||||
|
builder.append(", vectorMaskDensity: ").append(vectorMaskDensity);
|
||||||
|
}
|
||||||
|
if ((maskParams & 0x08) != 0) {
|
||||||
|
builder.append(", vectorMaskFeather: ").append(vectorMaskFeather);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user