From 9dcc30d8e91515b8844cd2327f8562cc7903a0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 17 Feb 2024 16:55:31 +0100 Subject: [PATCH] Fixed #2203 GFX - DefineSubImage with TGA bitmapFormat using bitmapFormat = 2 (DDS) in DefineExternalImages --- CHANGELOG.md | 2 + .../flash/tags/gfx/DefineExternalImage.java | 2 +- .../flash/tags/gfx/DefineExternalImage2.java | 2 +- .../flash/tags/gfx/DefineSubImage.java | 65 ++++++++++++++----- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9a04fcc4..4f53159d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ All notable changes to this project will be documented in this file. - [#2177] Leftover process when invalid SWF opened - now main window is shown - Opening files with "Open with FFDec" on windows did not use same instance - [#2183] AS1/2 Direct editation - case sensitive identifiers since SWF version 7 +- [#2203] GFX - DefineSubImage with TGA bitmapFormat ### Changed - [#2185] MochiCrypt no longer offered for auto decrypt, user needs to choose variant from "Use unpacker" menu @@ -3388,6 +3389,7 @@ Major version of SWF to XML export changed to 2. [#2178]: https://www.free-decompiler.com/flash/issues/2178 [#2177]: https://www.free-decompiler.com/flash/issues/2177 [#2183]: https://www.free-decompiler.com/flash/issues/2183 +[#2203]: https://www.free-decompiler.com/flash/issues/2203 [#2100]: https://www.free-decompiler.com/flash/issues/2100 [#2123]: https://www.free-decompiler.com/flash/issues/2123 [#2119]: https://www.free-decompiler.com/flash/issues/2119 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java index cfd85d686..c578cee7e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage.java @@ -201,7 +201,7 @@ public class DefineExternalImage extends ImageTag { } else { createFailedImage(); } - } else if (bitmapFormat == BITMAP_FORMAT2_DDS || bitmapFormat == BITMAP_FORMAT2_DDS) { + } else if (bitmapFormat == BITMAP_FORMAT2_DDS || bitmapFormat == BITMAP_FORMAT_DDS) { Path imagePath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName)); if (imagePath != null && imagePath.toFile().exists()) { try { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java index 5e50e4b17..4fd8823ea 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineExternalImage2.java @@ -227,7 +227,7 @@ public class DefineExternalImage2 extends ImageTag { } else { createFailedImage(); } - } else if (bitmapFormat == BITMAP_FORMAT2_DDS || bitmapFormat == BITMAP_FORMAT2_DDS) { + } else if (bitmapFormat == BITMAP_FORMAT2_DDS || bitmapFormat == BITMAP_FORMAT_DDS) { Path imagePath = getSwf().getFile() == null ? null : Paths.get(getSwf().getFile()).getParent().resolve(Paths.get(fileName)); if (imagePath != null && imagePath.toFile().exists()) { try { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java index e798604b2..45c46e7e5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineSubImage.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.gfx; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.gfx.TgaSupport; import com.jpexs.decompiler.flash.tags.TagInfo; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; @@ -35,6 +36,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Objects; +import javax.imageio.ImageIO; import net.npe.dds.DDSReader; /** @@ -182,6 +184,7 @@ public class DefineSubImage extends ImageTag { } int targetWidth = x2 - x1; int targetHeight = y2 - y1; + int bitmapFormat = image.bitmapFormat; if (!Objects.equals(cachedImageFilename, image.fileName) || !Objects.equals(cachedX1, (Integer) x1) @@ -194,25 +197,51 @@ public class DefineSubImage extends ImageTag { serImage = new SerializableImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR_PRE); serImage.fillTransparent(); return; - } - + } + Path imagePath = image.getSwf().getFile() == null ? null : Paths.get(image.getSwf().getFile()).getParent().resolve(Paths.get(image.fileName)); - if (imagePath != null && imagePath.toFile().exists()) { - try { - byte[] imageData = Files.readAllBytes(imagePath); - int[] pixels = DDSReader.read(imageData, DDSReader.ARGB, 0); - BufferedImage bufImage = new BufferedImage(DDSReader.getWidth(imageData), DDSReader.getHeight(imageData), BufferedImage.TYPE_INT_ARGB); - bufImage.getRaster().setDataElements(0, 0, bufImage.getWidth(), bufImage.getHeight(), pixels); - Image scaled = bufImage.getScaledInstance(image.targetWidth, image.targetHeight, Image.SCALE_DEFAULT); - bufImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB); - bufImage.getGraphics().drawImage(scaled, -x1, -y1, null); - serImage = new SerializableImage(bufImage); - cachedImageFilename = image.fileName; - cachedX1 = x1; - cachedX2 = x2; - cachedY1 = y1; - cachedY2 = y2; - } catch (IOException e) { + if (imagePath != null && imagePath.toFile().exists()) { + if (bitmapFormat == DefineExternalImage2.BITMAP_FORMAT2_JPEG + || bitmapFormat == DefineExternalImage2.BITMAP_FORMAT2_TGA + || bitmapFormat == DefineExternalImage2.BITMAP_FORMAT_TGA) { + try { + if (bitmapFormat == DefineExternalImage2.BITMAP_FORMAT2_TGA + || bitmapFormat == DefineExternalImage2.BITMAP_FORMAT_TGA) { + TgaSupport.init(); + } + BufferedImage bufImage = ImageIO.read(imagePath.toFile()); + Image scaled = bufImage.getScaledInstance(image.targetWidth, image.targetHeight, Image.SCALE_DEFAULT); + bufImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB); + bufImage.getGraphics().drawImage(scaled, -x1, -y1, null); + serImage = new SerializableImage(bufImage); + cachedImageFilename = image.fileName; + cachedX1 = x1; + cachedX2 = x2; + cachedY1 = y1; + cachedY2 = y2; + } catch (IOException ex) { + createFailedImage(); + } + } else if (bitmapFormat == DefineExternalImage2.BITMAP_FORMAT2_DDS + || bitmapFormat == DefineExternalImage2.BITMAP_FORMAT_DDS) { + try { + byte[] imageData = Files.readAllBytes(imagePath); + int[] pixels = DDSReader.read(imageData, DDSReader.ARGB, 0); + BufferedImage bufImage = new BufferedImage(DDSReader.getWidth(imageData), DDSReader.getHeight(imageData), BufferedImage.TYPE_INT_ARGB); + bufImage.getRaster().setDataElements(0, 0, bufImage.getWidth(), bufImage.getHeight(), pixels); + Image scaled = bufImage.getScaledInstance(image.targetWidth, image.targetHeight, Image.SCALE_DEFAULT); + bufImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB); + bufImage.getGraphics().drawImage(scaled, -x1, -y1, null); + serImage = new SerializableImage(bufImage); + cachedImageFilename = image.fileName; + cachedX1 = x1; + cachedX2 = x2; + cachedY1 = y1; + cachedY2 = y2; + } catch (IOException e) { + createFailedImage(); + } + } else { createFailedImage(); } } else {