#648: Simplified logic, code style fixes and clean up.

(cherry picked from commit b30fb4f8c3)
This commit is contained in:
Harald Kuhr
2021-12-28 16:49:41 +01:00
parent c0b2769e3b
commit b7192ae857
4 changed files with 85 additions and 104 deletions

View File

@@ -946,48 +946,8 @@ public final class PSDImageReader extends ImageReaderBase {
metadata.layerCount = layerCount;
if (pParseData && metadata.layerInfo == null) {
PSDLayerInfo[] layerInfos = new PSDLayerInfo[Math.abs(layerCount)];
Stack<List<PSDLayerInfo>> groupStack = new Stack<>();
List<PSDLayerInfo> groupedLayerInfo = null;
for (int i = 0; i < layerInfos.length; i++) {
PSDLayerInfo layerInfo = new PSDLayerInfo(header.largeFormat, imageInput);
layerInfos[i] = layerInfo;
if (layerInfo.sectionDividerSettingType == PSDLayerInfo.SectionDividerSetting.BOUNDING_SECTION_DIVIDER) {
if (groupedLayerInfo == null) {
groupedLayerInfo = new LinkedList<>();
groupStack.add(groupedLayerInfo);
} else {
groupStack.add(groupedLayerInfo);
groupedLayerInfo = new LinkedList<>();
}
layerInfo.sectionDivider = true;
}
else if (layerInfo.sectionDividerSettingType == PSDLayerInfo.SectionDividerSetting.OPEN_FOLDER ||
layerInfo.sectionDividerSettingType == PSDLayerInfo.SectionDividerSetting.CLOSED_FOLDER) {
// can't happen but for defense logic
if (groupedLayerInfo == null) {
continue;
}
for (PSDLayerInfo info : groupedLayerInfo) {
info.groupLayerId = layerInfo.getLayerId();
}
groupedLayerInfo = groupStack.pop();
groupedLayerInfo.add(layerInfo);
layerInfo.group = true;
}
else {
if (groupedLayerInfo != null) {
groupedLayerInfo.add(layerInfo);
}
}
}
metadata.layerInfo = Arrays.asList(layerInfos);
metadata.layerInfo = readLayerInfo(Math.abs(layerCount));
metadata.layersStart = imageInput.getStreamPosition();
}
long read = imageInput.getStreamPosition() - pos;
@@ -999,7 +959,6 @@ public final class PSDImageReader extends ImageReaderBase {
metadata.layerInfo = Collections.emptyList();
}
// Global LayerMaskInfo (18 bytes or more..?)
// 4 (length), 2 (colorSpace), 8 (4 * 2 byte color components), 2 (opacity %), 1 (kind), variable (pad)
long globalLayerMaskInfoLength = imageInput.readUnsignedInt(); // NOTE: Not long for PSB!
@@ -1030,6 +989,33 @@ public final class PSDImageReader extends ImageReaderBase {
}
}
private List<PSDLayerInfo> readLayerInfo(int layerCount) throws IOException {
PSDLayerInfo[] layerInfos = new PSDLayerInfo[layerCount];
List<PSDLayerInfo> groupedLayerInfo = Collections.emptyList();
for (int i = 0; i < layerInfos.length; i++) {
PSDLayerInfo layerInfo = new PSDLayerInfo(header.largeFormat, imageInput);
layerInfos[i] = layerInfo;
if (layerInfo.isDivider) {
groupedLayerInfo = new LinkedList<>();
}
else if (layerInfo.isGroup) {
for (PSDLayerInfo info : groupedLayerInfo) {
info.groupId = layerInfo.getLayerId();
}
groupedLayerInfo = Collections.emptyList();
}
else if (groupedLayerInfo != Collections.EMPTY_LIST) {
groupedLayerInfo.add(layerInfo);
}
}
return Arrays.asList(layerInfos);
}
private BufferedImage readLayerData(final int layerIndex, final ImageReadParam param) throws IOException {
final int width = getLayerWidth(layerIndex);
final int height = getLayerHeight(layerIndex);
@@ -1044,7 +1030,7 @@ public final class PSDImageReader extends ImageReaderBase {
// Even if raw/imageType has no alpha, the layers may still have alpha...
ImageTypeSpecifier imageType = getRawImageTypeForLayer(layerIndex);
BufferedImage layer = getDestination(param, getImageTypes(layerIndex + 1), Math.max(1, width), Math.max(1, height));
BufferedImage layer = getDestination(param, getImageTypes(layerIndex + 1), width, height);
imageInput.seek(findLayerStartPos(layerIndex));

View File

@@ -52,16 +52,15 @@ final class PSDLayerInfo {
final PSDLayerBlendMode blendMode;
final PSDLayerMaskData layerMaskData;
final PSDChannelSourceDestinationRange[] ranges;
private final String layerName;
private final String unicodeLayerName;
private String unicodeLayerName;
private int layerId;
private final int layerId;
Integer groupLayerId;
Boolean group = false;
Boolean sectionDivider = false;
SectionDividerSetting sectionDividerSettingType;
int groupId = -1;
final boolean isGroup;
final boolean isDivider;
PSDLayerInfo(final boolean largeFormat, final ImageInputStream pInput) throws IOException {
top = pInput.readInt();
@@ -114,6 +113,10 @@ final class PSDLayerInfo {
layerNameSize += skip;
}
int layerId = -1;
String unicodeLayerName = null;
int sectionDividerSettingType = 0;
// Parse "Additional layer data"
long additionalLayerInfoStart = pInput.getStreamPosition();
long expectedEnd = additionalLayerInfoStart + extraDataSize - layerMaskDataSize - 4 - layerBlendingDataSize - 4 - layerNameSize;
@@ -138,7 +141,6 @@ final class PSDLayerInfo {
// System.out.println("key: " + PSDUtil.intToStr(resourceKey));
// System.out.println("length: " + resourceLength);
switch (resourceKey) {
case PSD.luni:
unicodeLayerName = PSDUtil.readUnicodeString(pInput);
@@ -149,24 +151,37 @@ final class PSDLayerInfo {
if (resourceLength != 4) {
throw new IIOException(String.format("Expected layerId length == 4: %d", resourceLength));
}
layerId = pInput.readInt();
break;
case PSD.lsct:
sectionDividerSettingType = SectionDividerSetting.valueOf(pInput.readInt());
if (resourceLength < 4) {
throw new IIOException(String.format("Expected sectionDividerSetting length >= 4: %d", resourceLength));
}
sectionDividerSettingType = pInput.readInt();
// length >= 12: '8BIM' + 4byte blend mode, length >= 16, 4byte sub type
pInput.skipBytes(resourceLength - 4);
break;
default:
// TODO: Parse more data...
pInput.skipBytes(resourceLength);
break;
}
// Re-align in case we got the length incorrect
// Re-align in case we got the resource length incorrect
if (pInput.getStreamPosition() != resourceStart + resourceLength) {
pInput.seek(resourceStart + resourceLength);
}
}
this.layerId = layerId;
this.unicodeLayerName = unicodeLayerName;
isGroup = sectionDividerSettingType == 1 || sectionDividerSettingType == 2;
isDivider = sectionDividerSettingType == 3;
// Re-align in case we got the length incorrect
if (pInput.getStreamPosition() != expectedEnd) {
pInput.seek(expectedEnd);
@@ -197,26 +212,19 @@ final class PSDLayerInfo {
}
builder.append(", ranges: ").append(Arrays.toString(ranges));
builder.append(", layer name: \"").append(getLayerName()).append("\"");
builder.append(", layer id: ").append(getLayerId());
if (groupId != -1) {
builder.append(", group id: ").append(groupId);
}
if (isGroup) {
builder.append(", isGroup");
}
if (isDivider) {
builder.append(", isDivider");
}
builder.append("]");
return builder.toString();
}
public enum SectionDividerSetting {
LAYER(0), OPEN_FOLDER(1), CLOSED_FOLDER(2), BOUNDING_SECTION_DIVIDER(3);
SectionDividerSetting(int value) { this.value = value;}
private final int value;
public int value() { return value; }
public static SectionDividerSetting valueOf(int value){
for(SectionDividerSetting rt : SectionDividerSetting.values()){
if(rt.value == value){
return rt;
}
}
return null;
}
}
}

View File

@@ -37,6 +37,7 @@ import com.twelvemonkeys.imageio.metadata.iptc.IPTC;
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
import com.twelvemonkeys.lang.StringUtil;
import com.twelvemonkeys.util.FilterIterator;
import org.w3c.dom.Node;
import javax.imageio.metadata.IIOMetadataNode;
@@ -388,21 +389,21 @@ public final class PSDMetadata extends AbstractMetadata {
node.setAttribute("bottom", String.valueOf(psdLayerInfo.bottom));
node.setAttribute("right", String.valueOf(psdLayerInfo.right));
node.setAttribute("layerId", String.valueOf(psdLayerInfo.getLayerId()));
node.setAttribute("groupLayerId", String.valueOf(psdLayerInfo.groupLayerId));
if (psdLayerInfo.groupId != -1) {
node.setAttribute("groupId", String.valueOf(psdLayerInfo.groupId));
}
node.setAttribute("blendMode", PSDUtil.intToStr(psdLayerInfo.blendMode.blendMode));
node.setAttribute("opacity", String.valueOf(psdLayerInfo.blendMode.opacity)); // 0-255
node.setAttribute("clipping", getClippingValue(psdLayerInfo.blendMode.clipping)); // Enum: 0: Base, 1: Non-base, n: unknown
node.setAttribute("flags", String.valueOf(psdLayerInfo.blendMode.flags));
if ((psdLayerInfo.group)){
node.setAttribute("group", String.valueOf(psdLayerInfo.group));
if ((psdLayerInfo.isGroup)) {
node.setAttribute("group", "true");
}
if ((psdLayerInfo.sectionDivider)) {
node.setAttribute("sectionDivider", String.valueOf(psdLayerInfo.sectionDivider));
if ((psdLayerInfo.isDivider)) {
node.setAttribute("sectionDivider", "true");
}
if ((psdLayerInfo.blendMode.flags & 0x01) != 0) {
node.setAttribute("transparencyProtected", "true");