From dd32f9414d897f6369aabcfcd4ad08366056533c Mon Sep 17 00:00:00 2001 From: Pierre-Hugues Husson Date: Sat, 20 May 2017 13:02:33 +0200 Subject: [PATCH 1/3] In case of a grayscale + alpha 9patch, work-around JDK. Original code: https://worldwind31.arc.nasa.gov/svn/trunk/WorldWind/src/gov/nasa/worldwind/util/gdal/GDALUtils.java /JDK-5051418 Cf Bug #1508 --- .../res/decoder/Res9patchStreamDecoder.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) 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 9ce1be8a7c..d85132c085 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 @@ -20,6 +20,8 @@ import brut.androlib.err.CantFind9PatchChunk; import brut.util.ExtDataInput; import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; import java.io.*; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; @@ -40,7 +42,23 @@ public void decode(InputStream in, OutputStream out) int w = im.getWidth(), h = im.getHeight(); BufferedImage im2 = new BufferedImage(w+2, h+2, BufferedImage.TYPE_INT_ARGB); - im2.createGraphics().drawImage(im, 1, 1, w, h, null); + if(im.getType() == BufferedImage.TYPE_CUSTOM) { + //TODO: Ensure this is gray + alpha case? + Raster srcRaster = im.getRaster(); + WritableRaster dstRaster = im2.getRaster(); + int[] gray = null, alpha = null; + for (int y = 0; y < im.getHeight(); y++) { + gray = srcRaster.getSamples(0, y, w, 1, 0, gray); + alpha = srcRaster.getSamples(0, y, w, 1, 1, alpha); + + dstRaster.setSamples(1, y+1, w, 1, 0, gray); + dstRaster.setSamples(1, y+1, w, 1, 1, gray); + dstRaster.setSamples(1, y+1, w, 1, 2, gray); + dstRaster.setSamples(1, y+1, w, 1, 3, alpha); + } + } else { + im2.createGraphics().drawImage(im, 1, 1, w, h, null); + } NinePatch np = getNinePatch(data); drawHLine(im2, h + 1, np.padLeft + 1, w - np.padRight); From c3ea300b9681bf74f3a9721e546484ebe214308b Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 25 May 2017 07:02:10 -0400 Subject: [PATCH 2/3] Add unit-test for #1508 --- .../brut/androlib/BuildAndDecodeTest.java | 21 ++++++++++++++++++ .../drawable-xhdpi/btn_zoom_up_normal.9.png | Bin 0 -> 1985 bytes 2 files changed, 21 insertions(+) create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/drawable-xhdpi/btn_zoom_up_normal.9.png diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java index 4a0b252bd5..de49686c19 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.java @@ -350,6 +350,27 @@ public void ninePatchImageColorTest() throws BrutException, IOException { assertEquals(controlImage.getRGB(30, 30), testImage.getRGB(30, 30)); } + @Test + public void issue1508Test() throws BrutException, IOException { + char slash = File.separatorChar; + String location = slash + "res" + slash + "drawable-xhdpi" + slash; + + File control = new File((sTestOrigDir + location), "btn_zoom_up_normal.9.png"); + File test = new File((sTestNewDir + location), "btn_zoom_up_normal.9.png"); + + BufferedImage controlImage = ImageIO.read(control); + BufferedImage testImage = ImageIO.read(test); + + // 0, 0 = clear + assertEquals(controlImage.getRGB(0, 0), testImage.getRGB(0, 0)); + + // 30, 0 = black line + assertEquals(controlImage.getRGB(0, 30), testImage.getRGB(0, 30)); + + // 30, 30 = greyish button + assertEquals(controlImage.getRGB(30, 30), testImage.getRGB(30, 30)); + } + @Test public void drawableXxhdpiTest() throws BrutException, IOException { compareResFolder("drawable-xxhdpi"); diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/drawable-xhdpi/btn_zoom_up_normal.9.png b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/res/drawable-xhdpi/btn_zoom_up_normal.9.png new file mode 100644 index 0000000000000000000000000000000000000000..7f73df096ac9848483adbd095eb373cab9cf404a GIT binary patch literal 1985 zcmV;y2R`_TP)D1UvMDZzC~mm0h$7|m{7>$qFf&E4Nz=#7O@5j8?z{7n`M-0|_NGS< z(}Q|ghGqPR!(wojVHuWT879WZX39s*d(3N0Z^r81h!|<6L@*(YH)GEXVEQu8bvZ;I zIdX)Wo13Y=zTRwTXlS6iy1JI@*RS8-wryLE5_Bfx$h^z+>5662p+kr0$&)8kTU%>Z zu!ybjdCTF$hl`Y${>%?dKc;7=L_BcdfQWei{(ZCL!Gi~_@cExfNlCEGVCEO)FP|zT zWoBklQ&SVw)YO<2ckkXc;@-V`0`JZe)+UT`?u?MMZ{I$8{P;25zJ1%QxpU`ED-ikE zv18?|PpGoUejWKp+PinJhJ9g|4kpWv@D-g7-tgK#DIX|27jkIagCV5IQX+4skpHCqn zAvAUBR9diL0i~p*h);t6+8QS(CqX-hh}f#|pZHFAcsMOzzMM{Ou%@J> zgkoc3DKaurtT;J2S)#TE*5G~+b;E`Y`K;G0Q(KzWuU{`^P;qgwE{TbWp~;gc)7-gp zDJ?Bcezf5lO=QD)tc5kgj{;}`VcSw#S}KBaK3%D{^e2WZ<>lp>Tr*x(@w-y zt5%7Kr%s*HCD^JnX3UW7h#!u*Aw!1Hph1I#p+kp~v$L}ZHE!Iv)_JUf4=gAsATKX3 z5fRpixwhas?ps(`*vxwU#(cxrwi9v1iWO3bpFDX|my8`dR+8(0fB-sv{J6|%k@{(1 z?a`x0$<@_W&aveU?~lNx1civdGv6`2+KGs$grb|xRhK|OSRyP9sSV~(#0ofdtxFJHk=~##j*E*k zxduKFBEwP*!A^uFPM}*{EYeAj| z5fM1hXvoUSlBlbJz=G>-=dcD%h+)Hq(Ud7uBvpdN<>chFimV9=Yn(J`Qnu>o3^WQX zDAXY$UK8jM{Lq~{chZCj6U3@eKO<*E{->=$mkOY62Iv&@fB$|oA>tTU<_)71Cn6$38j*NSpjVK`ZQQs~!~kf6K~(%UB+z^I>=DptK#7Oz zNOACq^>7C`Mz2v59%4gCSR~Jvsq_Ys`DLSI8zv1AS#4c|#27+C5P+?XZ9I7JV6wNj zCp$Yk`GobML5u6WMO(o++Gq+}cX$9%{uAx+=Ha{}2D}UI&0f9^%BI1QrcK{ZN z#z96#hBPGLAJNGMIK~`AN8OCp7+Qg-STsC6Jw-@}ymIBrD%L20@l;mW*Hm{~9Bg+I z5nvlaOticZG|?{wS}zgTum)=(cw%CrY-gYe>FDU#U}a^M%o@#RzE*GjY)!qel7?h= z6S1>st^ii42?-IMoSf=xY-}>s%Y1C(ca$$Q{f-4?Q+Eg~T}6xRS`a}47D93$s15J&u%oMcwKUe>n9iS5F7uELd+0}o} zzGa5IsTv6o?iFQu&m^8UdYduudDhDB{j2|MTZUy=hGkfWWmv}lZIFddV>JE(@Jv*Z T*7Z_V00000NkvXXu0mjfV;{R( literal 0 HcmV?d00001 From a00da345b2b699cf8255ea3fd33fb889be79346a Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 25 May 2017 07:02:23 -0400 Subject: [PATCH 3/3] code style cleanup --- .../androlib/res/decoder/Res9patchStreamDecoder.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 d85132c085..ade5daa0e9 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 @@ -41,8 +41,8 @@ public void decode(InputStream in, OutputStream out) BufferedImage im = ImageIO.read(new ByteArrayInputStream(data)); int w = im.getWidth(), h = im.getHeight(); - BufferedImage im2 = new BufferedImage(w+2, h+2, BufferedImage.TYPE_INT_ARGB); - if(im.getType() == BufferedImage.TYPE_CUSTOM) { + BufferedImage im2 = new BufferedImage(w + 2, h + 2, BufferedImage.TYPE_INT_ARGB); + if (im.getType() == BufferedImage.TYPE_CUSTOM) { //TODO: Ensure this is gray + alpha case? Raster srcRaster = im.getRaster(); WritableRaster dstRaster = im2.getRaster(); @@ -51,10 +51,10 @@ public void decode(InputStream in, OutputStream out) gray = srcRaster.getSamples(0, y, w, 1, 0, gray); alpha = srcRaster.getSamples(0, y, w, 1, 1, alpha); - dstRaster.setSamples(1, y+1, w, 1, 0, gray); - dstRaster.setSamples(1, y+1, w, 1, 1, gray); - dstRaster.setSamples(1, y+1, w, 1, 2, gray); - dstRaster.setSamples(1, y+1, w, 1, 3, alpha); + dstRaster.setSamples(1, y + 1, w, 1, 0, gray); + dstRaster.setSamples(1, y + 1, w, 1, 1, gray); + dstRaster.setSamples(1, y + 1, w, 1, 2, gray); + dstRaster.setSamples(1, y + 1, w, 1, 3, alpha); } } else { im2.createGraphics().drawImage(im, 1, 1, w, h, null);