Merge branch 'fix-optical-inset' of https://github.com/phhusson/Apktool into phhusson-fix-optical-inset

This commit is contained in:
Connor Tumbleson 2017-06-08 15:52:14 -04:00
commit bd62f7e3e5

View File

@ -74,6 +74,36 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
drawVLine(im2, 0, yDivs[i] + 1, yDivs[i + 1]); 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); ImageIO.write(im2, "png", out);
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
@ -88,11 +118,18 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
private NinePatch getNinePatch(byte[] data) throws AndrolibException, private NinePatch getNinePatch(byte[] data) throws AndrolibException,
IOException { IOException {
ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data)); ExtDataInput di = new ExtDataInput(new ByteArrayInputStream(data));
find9patchChunk(di); find9patchChunk(di, NP_CHUNK_TYPE);
return NinePatch.decode(di); 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 { IOException {
di.skipBytes(8); di.skipBytes(8);
while (true) { while (true) {
@ -102,7 +139,7 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
} catch (IOException ex) { } catch (IOException ex) {
throw new CantFind9PatchChunk("Cant find nine patch chunk", ex); throw new CantFind9PatchChunk("Cant find nine patch chunk", ex);
} }
if (di.readInt() == NP_CHUNK_TYPE) { if (di.readInt() == magic) {
return; return;
} }
di.skipBytes(size + 4); di.skipBytes(size + 4);
@ -122,7 +159,9 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
} }
private static final int NP_CHUNK_TYPE = 0x6e705463; // npTc 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 NP_COLOR = 0xff000000;
private static final int OI_COLOR = 0xffff0000;
private static class NinePatch { private static class NinePatch {
public final int padLeft, padRight, padTop, padBottom; public final int padLeft, padRight, padTop, padBottom;
@ -156,4 +195,25 @@ public class Res9patchStreamDecoder implements ResStreamDecoder {
yDivs); 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);
}
}
} }