diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java index 9ce1be8a..680f4712 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/Res9patchStreamDecoder.java @@ -56,6 +56,36 @@ public class Res9patchStreamDecoder implements ResStreamDecoder { drawVLine(im2, 0, yDivs[i] + 1, yDivs[i + 1]); } + try { + OpticalInset oi = getOpticalInset(data); + + //As far as I know, only the length of the red lines are interesting + //not their positions + //So set them up in the corners + //TODO: Check we haven't already filled it with NP_COLOR? + for(int i = 0; i < oi.layoutBoundsLeft; i++) { + int x = 1 + i; + im2.setRGB(x, h + 1, OI_COLOR); + } + + for(int i = 0; i < oi.layoutBoundsRight; i++) { + int x = w - i; + im2.setRGB(x, h + 1, OI_COLOR); + } + + for(int i = 0; i < oi.layoutBoundsTop; i++) { + int y = 1 + i; + im2.setRGB(w + 1, y, OI_COLOR); + } + + for(int i = 0; i < oi.layoutBoundsBottom; i++) { + int y = h - i; + im2.setRGB(w + 1, y, OI_COLOR); + } + } catch(CantFind9PatchChunk t) { + //This chunk might not exist + } + ImageIO.write(im2, "png", out); } catch (IOException ex) { throw new AndrolibException(ex); @@ -70,11 +100,18 @@ public class Res9patchStreamDecoder implements ResStreamDecoder { private NinePatch getNinePatch(byte[] data) throws AndrolibException, IOException { ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); - find9patchChunk(di); + find9patchChunk(di, NP_CHUNK_TYPE); return NinePatch.decode(di); } - private void find9patchChunk(DataInput di) throws AndrolibException, + private OpticalInset getOpticalInset(byte[] data) throws AndrolibException, + IOException { + ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); + find9patchChunk(di, OI_CHUNK_TYPE); + return OpticalInset.decode(di); + } + + private void find9patchChunk(DataInput di, int magic) throws AndrolibException, IOException { di.skipBytes(8); while (true) { @@ -84,7 +121,7 @@ public class Res9patchStreamDecoder implements ResStreamDecoder { } catch (IOException ex) { throw new CantFind9PatchChunk("Cant find nine patch chunk", ex); } - if (di.readInt() == NP_CHUNK_TYPE) { + if (di.readInt() == magic) { return; } di.skipBytes(size + 4); @@ -104,7 +141,9 @@ public class Res9patchStreamDecoder implements ResStreamDecoder { } private static final int NP_CHUNK_TYPE = 0x6e705463; // npTc + private static final int OI_CHUNK_TYPE = 0x6e704c62; // npLb private static final int NP_COLOR = 0xff000000; + private static final int OI_COLOR = 0xffff0000; private static class NinePatch { public final int padLeft, padRight, padTop, padBottom; @@ -138,4 +177,25 @@ public class Res9patchStreamDecoder implements ResStreamDecoder { yDivs); } } + + private static class OpticalInset { + public final int layoutBoundsLeft, layoutBoundsTop, layoutBoundsRight, layoutBoundsBottom; + + public OpticalInset(int layoutBoundsLeft, int layoutBoundsTop, + int layoutBoundsRight, int layoutBoundsBottom) { + this.layoutBoundsLeft = layoutBoundsLeft; + this.layoutBoundsTop = layoutBoundsTop; + this.layoutBoundsRight = layoutBoundsRight; + this.layoutBoundsBottom = layoutBoundsBottom; + } + + public static OpticalInset decode(ExtDataInput di) throws IOException { + int layoutBoundsLeft = Integer.reverseBytes(di.readInt()); + int layoutBoundsTop = Integer.reverseBytes(di.readInt()); + int layoutBoundsRight = Integer.reverseBytes(di.readInt()); + int layoutBoundsBottom = Integer.reverseBytes(di.readInt()); + return new OpticalInset(layoutBoundsLeft, layoutBoundsTop, + layoutBoundsRight, layoutBoundsBottom); + } + } }