get image dimension without loading the image

This commit is contained in:
honfika@gmail.com
2015-07-20 15:54:40 +02:00
parent 37dc877b16
commit ecc0cd3f15
10 changed files with 122 additions and 15 deletions

View File

@@ -181,7 +181,7 @@ public class HighlightedTextWriter extends GraphTextWriter {
HighlightData ndata = new HighlightData();
ndata.merge(itemPos.data);
ndata.merge(data);
ndata.offset = src.getOffset() + pos + 1;
ndata.offset = src.getOffset() + pos;
h = new Highlighting(sb.length() - newLineCount, ndata, HighlightType.OFFSET, str);
instructionHilights.add(h);
}

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.helpers;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.helpers.Helper;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -26,10 +27,12 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.monte.media.jpeg.CMYKJPEGImageReader;
import org.monte.media.jpeg.CMYKJPEGImageReaderSpi;
@@ -136,4 +139,23 @@ public class ImageHelper {
throw new Error("Unsuported image format: " + format);
}
public static Dimension getDimesion(InputStream input) throws IOException {
try (ImageInputStream in = ImageIO.createImageInputStream(input)) {
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(in);
return new Dimension(reader.getWidth(0), reader.getHeight(0));
} finally {
reader.dispose();
}
}
} catch (IOException ex) {
}
BufferedImage image = read(input);
return new Dimension(image.getWidth(), image.getHeight());
}
}

View File

@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -145,4 +146,19 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
}
return null;
}
@Override
public Dimension getImageDimension() {
if (cachedImage != null) {
return new Dimension(cachedImage.getWidth(), cachedImage.getHeight());
}
try {
return ImageHelper.getDimesion(getOriginalImageData());
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
}
}

View File

@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
@@ -140,8 +141,8 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
throw new IOException("Only Jpeg can have alpha channel.");
}
SerializableImage image = getImage();
if (data == null || data.length != image.getWidth() * image.getHeight()) {
Dimension dimension = getImageDimension();
if (data == null || data.length != dimension.getWidth() * dimension.getHeight()) {
throw new IOException("Data length must match the size of the image.");
}
@@ -210,4 +211,21 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
}
return null;
}
@Override
public Dimension getImageDimension() {
if (cachedImage != null) {
return new Dimension(cachedImage.getWidth(), cachedImage.getHeight());
}
try {
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
return ImageHelper.getDimesion(bis);
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
}
}

View File

@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
@@ -145,8 +146,8 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
throw new IOException("Only Jpeg can have alpha channel.");
}
SerializableImage image = getImage();
if (data == null || data.length != image.getWidth() * image.getHeight()) {
Dimension dimension = getImageDimension();
if (data == null || data.length != dimension.getWidth() * dimension.getHeight()) {
throw new IOException("Data length must match the size of the image.");
}
@@ -179,7 +180,6 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
return cachedImage;
}
try {
BufferedImage image = ImageHelper.read(new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength()));
if (image == null) {
Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to load image");
@@ -212,4 +212,20 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
}
return null;
}
@Override
public Dimension getImageDimension() {
if (cachedImage != null) {
return new Dimension(cachedImage.getWidth(), cachedImage.getHeight());
}
try {
ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength());
return ImageHelper.getDimesion(bis);
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
return null;
}
}

View File

@@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -271,4 +272,9 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
return bi;
}
@Override
public Dimension getImageDimension() {
return new Dimension(bitmapWidth, bitmapHeight);
}
}

View File

@@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -275,4 +276,9 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
return bi;
}
@Override
public Dimension getImageDimension() {
return new Dimension(bitmapWidth, bitmapHeight);
}
}

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -158,6 +159,24 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
return null;
}
@Override
public Dimension getImageDimension() {
if (cachedImage != null) {
return new Dimension(cachedImage.getWidth(), cachedImage.getHeight());
}
InputStream imageStream = getOriginalImageData();
if (imageStream != null) {
try {
return ImageHelper.getDimesion(imageStream);
} catch (IOException ex) {
Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex);
}
}
return null;
}
@Override
public void handleEvent(Tag tag) {
// cache should be cleared when Jtt tag changes

View File

@@ -41,6 +41,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Dimension;
import java.awt.Shape;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -68,6 +69,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
public abstract SerializableImage getImage();
public abstract Dimension getImageDimension();
public abstract void setImage(byte[] data) throws IOException;
public abstract ImageFormat getImageFormat();
@@ -231,9 +234,9 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
@Override
public RECT getRect(Set<BoundedTag> added) {
SerializableImage image = getImage();
int widthInTwips = (int) (image.getWidth() * SWF.unitDivisor);
int heightInTwips = (int) (image.getHeight() * SWF.unitDivisor);
Dimension dimension = getImageDimension();
int widthInTwips = (int) (dimension.getWidth() * SWF.unitDivisor);
int heightInTwips = (int) (dimension.getHeight() * SWF.unitDivisor);
return new RECT(0, widthInTwips, 0, heightInTwips);
}
@@ -282,9 +285,9 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
@Override
public void getTagInfo(TagInfo tagInfo) {
super.getTagInfo(tagInfo);
SerializableImage image = getImage();
tagInfo.addInfo("general", "width", image.getWidth());
tagInfo.addInfo("general", "height", image.getHeight());
Dimension dimension = getImageDimension();
tagInfo.addInfo("general", "width", dimension.getWidth());
tagInfo.addInfo("general", "height", dimension.getHeight());
}
@Override