lazy loading of shaperecords in DefineShape tags

This commit is contained in:
honfika@gmail.com
2014-11-09 14:11:50 +01:00
parent f3690a0e3c
commit ebe45ebc7f
9 changed files with 97 additions and 26 deletions

View File

@@ -980,7 +980,7 @@ public class SWFInputStream implements AutoCloseable {
public Tag call() throws Exception {
DumpInfo di = dumpInfo;
try {
Tag t = resolveTag(tag, level, parallel, skipUnusualTags);
Tag t = resolveTag(tag, level, parallel, skipUnusualTags, true);
if (dumpInfo != null && t != null) {
dumpInfo.name = t.getName();
}
@@ -1048,7 +1048,7 @@ public class SWFInputStream implements AutoCloseable {
switch (tag.getId()) {
case FileAttributesTag.ID: //FileAttributes
if (tag instanceof TagStub) {
tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags);
tag = resolveTag((TagStub) tag, level, parallel, skipUnusualTags, true);
}
FileAttributesTag fileAttributes = (FileAttributesTag) tag;
if (fileAttributes.actionScript3) {
@@ -1123,7 +1123,7 @@ public class SWFInputStream implements AutoCloseable {
return tags;
}
public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags) throws InterruptedException {
public static Tag resolveTag(TagStub tag, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws InterruptedException {
Tag ret;
ByteArrayRange data = tag.getOriginalRange();
@@ -1139,7 +1139,7 @@ public class SWFInputStream implements AutoCloseable {
ret = new ShowFrameTag(swf, data);
break;
case 2:
ret = new DefineShapeTag(sis, data);
ret = new DefineShapeTag(sis, data, lazy);
break;
//case 3: FreeCharacter
case 4:
@@ -1195,7 +1195,7 @@ public class SWFInputStream implements AutoCloseable {
ret = new DefineBitsJPEG2Tag(sis, data);
break;
case 22:
ret = new DefineShape2Tag(sis, data);
ret = new DefineShape2Tag(sis, data, lazy);
break;
case 23:
ret = new DefineButtonCxformTag(sis, data);
@@ -1215,7 +1215,7 @@ public class SWFInputStream implements AutoCloseable {
//case 30:
//case 31: FreeAll
case 32:
ret = new DefineShape3Tag(sis, data);
ret = new DefineShape3Tag(sis, data, lazy);
break;
case 33:
ret = new DefineText2Tag(sis, data);
@@ -1332,7 +1332,7 @@ public class SWFInputStream implements AutoCloseable {
ret = new DoABCDefineTag(sis, data);
break;
case 83:
ret = new DefineShape4Tag(sis, data);
ret = new DefineShape4Tag(sis, data, lazy);
break;
case 84:
ret = new DefineMorphShape2Tag(sis, data);
@@ -1459,7 +1459,7 @@ public class SWFInputStream implements AutoCloseable {
if (resolve) {
DumpInfo di = dumpInfo;
try {
ret = resolveTag(tagStub, level, parallel, skipUnusualTags);
ret = resolveTag(tagStub, level, parallel, skipUnusualTags, true);
} catch (Exception ex) {
tagDataStream.endDumpLevelUntil(di);
logger.log(Level.SEVERE, "Problem in " + timelined.toString(), ex);

View File

@@ -30,6 +30,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DefineShape2Tag extends ShapeTag {
@@ -39,6 +41,8 @@ public class DefineShape2Tag extends ShapeTag {
public SHAPEWITHSTYLE shapes;
public static final int ID = 22;
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 2;
@@ -46,6 +50,17 @@ public class DefineShape2Tag extends ShapeTag {
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(2, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape2Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@@ -84,11 +99,15 @@ public class DefineShape2Tag extends ShapeTag {
shapes = SHAPEWITHSTYLE.createEmpty(2);
}
public DefineShape2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
public DefineShape2Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
super(sis.getSwf(), ID, "DefineShape2", data);
shapeId = sis.readUI16("shapeId");
shapeBounds = sis.readRECT("shapeBounds");
shapes = sis.readSHAPEWITHSTYLE(2, false, "shapes");
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(2, false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
}
/**

View File

@@ -30,6 +30,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DefineShape3Tag extends ShapeTag {
@@ -39,6 +41,8 @@ public class DefineShape3Tag extends ShapeTag {
public SHAPEWITHSTYLE shapes;
public static final int ID = 32;
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 3;
@@ -46,6 +50,17 @@ public class DefineShape3Tag extends ShapeTag {
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape3Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@@ -84,11 +99,15 @@ public class DefineShape3Tag extends ShapeTag {
shapes = SHAPEWITHSTYLE.createEmpty(3);
}
public DefineShape3Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
public DefineShape3Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
super(sis.getSwf(), ID, "DefineShape3", data);
shapeId = sis.readUI16("shapeId");
shapeBounds = sis.readRECT("shapeBounds");
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(3, false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
}
/**

View File

@@ -31,6 +31,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DefineShape4Tag extends ShapeTag {
@@ -47,6 +49,8 @@ public class DefineShape4Tag extends ShapeTag {
public SHAPEWITHSTYLE shapes;
public static final int ID = 83;
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
return 4;
@@ -54,6 +58,17 @@ public class DefineShape4Tag extends ShapeTag {
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShape4Tag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@@ -93,7 +108,7 @@ public class DefineShape4Tag extends ShapeTag {
shapes = SHAPEWITHSTYLE.createEmpty(4);
}
public DefineShape4Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
public DefineShape4Tag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
super(sis.getSwf(), ID, "DefineShape4", data);
shapeId = sis.readUI16("shapeId");
shapeBounds = sis.readRECT("shapeBounds");
@@ -102,7 +117,11 @@ public class DefineShape4Tag extends ShapeTag {
usesFillWindingRule = sis.readUB(1, "usesFillWindingRule") == 1;
usesNonScalingStrokes = sis.readUB(1, "usesNonScalingStrokes") == 1;
usesScalingStrokes = sis.readUB(1, "usesScalingStrokes") == 1;
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(4, false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
}
/**

View File

@@ -29,6 +29,8 @@ import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DefineShapeTag extends ShapeTag {
@@ -37,6 +39,8 @@ public class DefineShapeTag extends ShapeTag {
public RECT shapeBounds;
public SHAPEWITHSTYLE shapes;
public static final int ID = 2;
private ByteArrayRange shapeData;
@Override
public int getShapeNum() {
@@ -45,6 +49,17 @@ public class DefineShapeTag extends ShapeTag {
@Override
public SHAPEWITHSTYLE getShapes() {
if (shapes == null && shapeData != null) {
try {
SWFInputStream sis = new SWFInputStream(swf, shapeData.getArray(), 0, shapeData.getPos() + shapeData.getLength());
sis.seek(shapeData.getPos());
shapes = sis.readSHAPEWITHSTYLE(1, false, "shapes");
shapeData = null; // not needed anymore, give it to GC
} catch (IOException ex) {
Logger.getLogger(DefineShapeTag.class.getName()).log(Level.SEVERE, null, ex);
}
}
return shapes;
}
@@ -78,11 +93,15 @@ public class DefineShapeTag extends ShapeTag {
shapes = SHAPEWITHSTYLE.createEmpty(1);
}
public DefineShapeTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
public DefineShapeTag(SWFInputStream sis, ByteArrayRange data, boolean lazy) throws IOException {
super(sis.getSwf(), ID, "DefineShape", data);
shapeId = sis.readUI16("shapeId");
shapeBounds = sis.readRECT("shapeBounds");
shapes = sis.readSHAPEWITHSTYLE(1, false, "shapes");
if (!lazy) {
shapes = sis.readSHAPEWITHSTYLE(1, false, "shapes");
} else {
shapeData = new ByteArrayRange(data.getArray(), (int) sis.getPos(), sis.available());
}
}
/**