diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 18a1fbf..b57d4db 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -24,7 +24,10 @@
 sources := \
 	compile/IdAssigner.cpp \
 	compile/InlineXmlFormatParser.cpp \
+	compile/NinePatch.cpp \
 	compile/Png.cpp \
+	compile/PngChunkFilter.cpp \
+	compile/PngCrunch.cpp \
 	compile/PseudolocaleGenerator.cpp \
 	compile/Pseudolocalizer.cpp \
 	compile/XmlIdCollector.cpp \
@@ -34,6 +37,7 @@
 	flatten/XmlFlattener.cpp \
 	io/File.cpp \
 	io/FileSystem.cpp \
+	io/Io.cpp \
 	io/ZipArchive.cpp \
 	link/AutoVersioner.cpp \
 	link/ManifestFixer.cpp \
@@ -84,6 +88,7 @@
 testSources := \
 	compile/IdAssigner_test.cpp \
 	compile/InlineXmlFormatParser_test.cpp \
+	compile/NinePatch_test.cpp \
 	compile/PseudolocaleGenerator_test.cpp \
 	compile/Pseudolocalizer_test.cpp \
 	compile/XmlIdCollector_test.cpp \
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index e0f37ec..dbd8062 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -36,6 +36,8 @@
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/io/coded_stream.h>
 
+#include <android-base/errors.h>
+#include <android-base/file.h>
 #include <dirent.h>
 #include <fstream>
 #include <string>
@@ -359,6 +361,9 @@
 static bool compileXml(IAaptContext* context, const CompileOptions& options,
                        const ResourcePathData& pathData, IArchiveWriter* writer,
                        const std::string& outputPath) {
+    if (context->verbose()) {
+        context->getDiagnostics()->note(DiagMessage(pathData.source) << "compiling XML");
+    }
 
     std::unique_ptr<xml::XmlResource> xmlRes;
     {
@@ -431,9 +436,43 @@
     return true;
 }
 
+class BigBufferOutputStream : public io::OutputStream {
+public:
+    explicit BigBufferOutputStream(BigBuffer* buffer) : mBuffer(buffer) {
+    }
+
+    bool Next(void** data, int* len) override {
+        size_t count;
+        *data = mBuffer->nextBlock(&count);
+        *len = static_cast<int>(count);
+        return true;
+    }
+
+    void BackUp(int count) override {
+        mBuffer->backUp(count);
+    }
+
+    int64_t ByteCount() const override {
+        return mBuffer->size();
+    }
+
+    bool HadError() const override {
+        return false;
+    }
+
+private:
+    BigBuffer* mBuffer;
+
+    DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream);
+};
+
 static bool compilePng(IAaptContext* context, const CompileOptions& options,
                        const ResourcePathData& pathData, IArchiveWriter* writer,
                        const std::string& outputPath) {
+    if (context->verbose()) {
+        context->getDiagnostics()->note(DiagMessage(pathData.source) << "compiling PNG");
+    }
+
     BigBuffer buffer(4096);
     ResourceFile resFile;
     resFile.name = ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
@@ -441,16 +480,90 @@
     resFile.source = pathData.source;
 
     {
-        std::ifstream fin(pathData.source.path, std::ifstream::binary);
-        if (!fin) {
-            context->getDiagnostics()->error(DiagMessage(pathData.source) << strerror(errno));
+        std::string content;
+        if (!android::base::ReadFileToString(pathData.source.path, &content)) {
+            context->getDiagnostics()->error(DiagMessage(pathData.source)
+                                             << android::base::SystemErrorCodeToString(errno));
             return false;
         }
 
-        Png png(context->getDiagnostics());
-        if (!png.process(pathData.source, &fin, &buffer, {})) {
+        BigBuffer crunchedPngBuffer(4096);
+        BigBufferOutputStream crunchedPngBufferOut(&crunchedPngBuffer);
+
+        // Ensure that we only keep the chunks we care about if we end up
+        // using the original PNG instead of the crunched one.
+        PngChunkFilter pngChunkFilter(content);
+        std::unique_ptr<Image> image = readPng(context, &pngChunkFilter);
+        if (!image) {
             return false;
         }
+
+        std::unique_ptr<NinePatch> ninePatch;
+        if (pathData.extension == "9.png") {
+            std::string err;
+            ninePatch = NinePatch::create(image->rows.get(), image->width, image->height, &err);
+            if (!ninePatch) {
+                context->getDiagnostics()->error(DiagMessage() << err);
+                return false;
+            }
+
+            // Remove the 1px border around the NinePatch.
+            // Basically the row array is shifted up by 1, and the length is treated
+            // as height - 2.
+            // For each row, shift the array to the left by 1, and treat the length as width - 2.
+            image->width -= 2;
+            image->height -= 2;
+            memmove(image->rows.get(), image->rows.get() + 1, image->height * sizeof(uint8_t**));
+            for (int32_t h = 0; h < image->height; h++) {
+                memmove(image->rows[h], image->rows[h] + 4, image->width * 4);
+            }
+
+            if (context->verbose()) {
+                context->getDiagnostics()->note(DiagMessage(pathData.source)
+                                                << "9-patch: " << *ninePatch);
+            }
+        }
+
+        // Write the crunched PNG.
+        if (!writePng(context, image.get(), ninePatch.get(), &crunchedPngBufferOut, {})) {
+            return false;
+        }
+
+        if (ninePatch != nullptr
+                || crunchedPngBufferOut.ByteCount() <= pngChunkFilter.ByteCount()) {
+            // No matter what, we must use the re-encoded PNG, even if it is larger.
+            // 9-patch images must be re-encoded since their borders are stripped.
+            buffer.appendBuffer(std::move(crunchedPngBuffer));
+        } else {
+            // The re-encoded PNG is larger than the original, and there is
+            // no mandatory transformation. Use the original.
+            if (context->verbose()) {
+                context->getDiagnostics()->note(DiagMessage(pathData.source)
+                                                << "original PNG is smaller than crunched PNG"
+                                                << ", using original");
+            }
+
+            PngChunkFilter pngChunkFilterAgain(content);
+            BigBuffer filteredPngBuffer(4096);
+            BigBufferOutputStream filteredPngBufferOut(&filteredPngBuffer);
+            io::copy(&filteredPngBufferOut, &pngChunkFilterAgain);
+            buffer.appendBuffer(std::move(filteredPngBuffer));
+        }
+
+        if (context->verbose()) {
+            // For debugging only, use the legacy PNG cruncher and compare the resulting file sizes.
+            // This will help catch exotic cases where the new code may generate larger PNGs.
+            std::stringstream legacyStream(content);
+            BigBuffer legacyBuffer(4096);
+            Png png(context->getDiagnostics());
+            if (!png.process(pathData.source, &legacyStream, &legacyBuffer, {})) {
+                return false;
+            }
+
+            context->getDiagnostics()->note(DiagMessage(pathData.source)
+                                            << "legacy=" << legacyBuffer.size()
+                                            << " new=" << buffer.size());
+        }
     }
 
     if (!writeHeaderAndBufferToWriter(outputPath, resFile, buffer, writer,
@@ -463,6 +576,10 @@
 static bool compileFile(IAaptContext* context, const CompileOptions& options,
                         const ResourcePathData& pathData, IArchiveWriter* writer,
                         const std::string& outputPath) {
+    if (context->verbose()) {
+        context->getDiagnostics()->note(DiagMessage(pathData.source) << "compiling file");
+    }
+
     BigBuffer buffer(256);
     ResourceFile resFile;
     resFile.name = ResourceName({}, *parseResourceType(pathData.resourceDir), pathData.name);
diff --git a/tools/aapt2/compile/Image.h b/tools/aapt2/compile/Image.h
new file mode 100644
index 0000000..fda6a3a
--- /dev/null
+++ b/tools/aapt2/compile/Image.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_COMPILE_IMAGE_H
+#define AAPT_COMPILE_IMAGE_H
+
+#include <android-base/macros.h>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+/**
+ * An in-memory image, loaded from disk, with pixels in RGBA_8888 format.
+ */
+class Image {
+public:
+    explicit Image() = default;
+
+    /**
+     * A `height` sized array of pointers, where each element points to a
+     * `width` sized row of RGBA_8888 pixels.
+     */
+    std::unique_ptr<uint8_t*[]> rows;
+
+    /**
+     * The width of the image in RGBA_8888 pixels. This is int32_t because of 9-patch data
+     * format limitations.
+     */
+    int32_t width = 0;
+
+    /**
+     * The height of the image in RGBA_8888 pixels. This is int32_t because of 9-patch data
+     * format limitations.
+     */
+    int32_t height = 0;
+
+    /**
+     * Buffer to the raw image data stored sequentially.
+     * Use `rows` to access the data on a row-by-row basis.
+     */
+    std::unique_ptr<uint8_t[]> data;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(Image);
+};
+
+/**
+ * A range of pixel values, starting at 'start' and ending before 'end' exclusive. Or rather [a, b).
+ */
+struct Range {
+    int32_t start = 0;
+    int32_t end = 0;
+
+    explicit Range() = default;
+    inline explicit Range(int32_t s, int32_t e) : start(s), end(e) {
+    }
+};
+
+inline bool operator==(const Range& left, const Range& right) {
+    return left.start == right.start && left.end == right.end;
+}
+
+/**
+ * Inset lengths from all edges of a rectangle. `left` and `top` are measured from the left and top
+ * edges, while `right` and `bottom` are measured from the right and bottom edges, respectively.
+ */
+struct Bounds {
+    int32_t left = 0;
+    int32_t top = 0;
+    int32_t right = 0;
+    int32_t bottom = 0;
+
+    explicit Bounds() = default;
+    inline explicit Bounds(int32_t l, int32_t t, int32_t r, int32_t b) :
+            left(l), top(t), right(r), bottom(b) {
+    }
+
+    bool nonZero() const;
+};
+
+inline bool Bounds::nonZero() const {
+    return left != 0 || top != 0 || right != 0 || bottom != 0;
+}
+
+inline bool operator==(const Bounds& left, const Bounds& right) {
+    return left.left == right.left && left.top == right.top &&
+            left.right == right.right && left.bottom == right.bottom;
+}
+
+/**
+ * Contains 9-patch data from a source image. All measurements exclude the 1px border of the
+ * source 9-patch image.
+ */
+class NinePatch {
+public:
+    static std::unique_ptr<NinePatch> create(uint8_t** rows,
+                                             const int32_t width, const int32_t height,
+                                             std::string* errOut);
+
+    /**
+     * Packs the RGBA_8888 data pointed to by pixel into a uint32_t
+     * with format 0xAARRGGBB (the way 9-patch expects it).
+     */
+    static uint32_t packRGBA(const uint8_t* pixel);
+
+    /**
+     * 9-patch content padding/insets. All positions are relative to the 9-patch
+     * NOT including the 1px thick source border.
+     */
+    Bounds padding;
+
+    /**
+     * Optical layout bounds/insets. This overrides the padding for
+     * layout purposes. All positions are relative to the 9-patch
+     * NOT including the 1px thick source border.
+     * See https://developer.android.com/about/versions/android-4.3.html#OpticalBounds
+     */
+    Bounds layoutBounds;
+
+    /**
+     * Outline of the image, calculated based on opacity.
+     */
+    Bounds outline;
+
+    /**
+     * The computed radius of the outline. If non-zero, the outline is a rounded-rect.
+     */
+    float outlineRadius = 0.0f;
+
+    /**
+     * The largest alpha value within the outline.
+     */
+    uint32_t outlineAlpha = 0x000000ffu;
+
+    /**
+     * Horizontal regions of the image that are stretchable.
+     * All positions are relative to the 9-patch
+     * NOT including the 1px thick source border.
+     */
+    std::vector<Range> horizontalStretchRegions;
+
+    /**
+     * Vertical regions of the image that are stretchable.
+     * All positions are relative to the 9-patch
+     * NOT including the 1px thick source border.
+     */
+    std::vector<Range> verticalStretchRegions;
+
+    /**
+     * The colors within each region, fixed or stretchable.
+     * For w*h regions, the color of region (x,y) is addressable
+     * via index y*w + x.
+     */
+    std::vector<uint32_t> regionColors;
+
+    /**
+     * Returns serialized data containing the original basic 9-patch meta data.
+     * Optical layout bounds and round rect outline data must be serialized
+     * separately using serializeOpticalLayoutBounds() and serializeRoundedRectOutline().
+     */
+    std::unique_ptr<uint8_t[]> serializeBase(size_t* outLen) const;
+
+    /**
+     * Serializes the layout bounds.
+     */
+    std::unique_ptr<uint8_t[]> serializeLayoutBounds(size_t* outLen) const;
+
+    /**
+     * Serializes the rounded-rect outline.
+     */
+    std::unique_ptr<uint8_t[]> serializeRoundedRectOutline(size_t* outLen) const;
+
+private:
+    explicit NinePatch() = default;
+
+    DISALLOW_COPY_AND_ASSIGN(NinePatch);
+};
+
+::std::ostream& operator<<(::std::ostream& out, const Range& range);
+::std::ostream& operator<<(::std::ostream& out, const Bounds& bounds);
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch);
+
+} // namespace aapt
+
+#endif /* AAPT_COMPILE_IMAGE_H */
diff --git a/tools/aapt2/compile/NinePatch.cpp b/tools/aapt2/compile/NinePatch.cpp
new file mode 100644
index 0000000..408ecf7
--- /dev/null
+++ b/tools/aapt2/compile/NinePatch.cpp
@@ -0,0 +1,671 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compile/Image.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace aapt {
+
+// Colors in the format 0xAARRGGBB (the way 9-patch expects it).
+constexpr static const uint32_t kColorOpaqueWhite = 0xffffffffu;
+constexpr static const uint32_t kColorOpaqueBlack = 0xff000000u;
+constexpr static const uint32_t kColorOpaqueRed   = 0xffff0000u;
+
+constexpr static const uint32_t kPrimaryColor = kColorOpaqueBlack;
+constexpr static const uint32_t kSecondaryColor = kColorOpaqueRed;
+
+/**
+ * Returns the alpha value encoded in the 0xAARRGBB encoded pixel.
+ */
+static uint32_t getAlpha(uint32_t color);
+
+/**
+ * Determines whether a color on an ImageLine is valid.
+ * A 9patch image may use a transparent color as neutral,
+ * or a fully opaque white color as neutral, based on the
+ * pixel color at (0,0) of the image. One or the other is fine,
+ * but we need to ensure consistency throughout the image.
+ */
+class ColorValidator {
+public:
+    virtual ~ColorValidator() = default;
+
+    /**
+     * Returns true if the color specified is a neutral color
+     * (no padding, stretching, or optical bounds).
+     */
+    virtual bool isNeutralColor(uint32_t color) const = 0;
+
+    /**
+     * Returns true if the color is either a neutral color
+     * or one denoting padding, stretching, or optical bounds.
+     */
+    bool isValidColor(uint32_t color) const {
+        switch (color) {
+        case kPrimaryColor:
+        case kSecondaryColor:
+            return true;
+        }
+        return isNeutralColor(color);
+    }
+};
+
+// Walks an ImageLine and records Ranges of primary and secondary colors.
+// The primary color is black and is used to denote a padding or stretching range,
+// depending on which border we're iterating over.
+// The secondary color is red and is used to denote optical bounds.
+//
+// An ImageLine is a templated-interface that would look something like this if it
+// were polymorphic:
+//
+// class ImageLine {
+// public:
+//      virtual int32_t getLength() const = 0;
+//      virtual uint32_t getColor(int32_t idx) const = 0;
+// };
+//
+template <typename ImageLine>
+static bool fillRanges(const ImageLine* imageLine,
+                       const ColorValidator* colorValidator,
+                       std::vector<Range>* primaryRanges,
+                       std::vector<Range>* secondaryRanges,
+                       std::string* err) {
+    const int32_t length = imageLine->getLength();
+
+    uint32_t lastColor = 0xffffffffu;
+    for (int32_t idx = 1; idx < length - 1; idx++) {
+        const uint32_t color = imageLine->getColor(idx);
+        if (!colorValidator->isValidColor(color)) {
+            *err = "found an invalid color";
+            return false;
+        }
+
+        if (color != lastColor) {
+            // We are ending a range. Which range?
+            // note: encode the x offset without the final 1 pixel border.
+            if (lastColor == kPrimaryColor) {
+                primaryRanges->back().end = idx - 1;
+            } else if (lastColor == kSecondaryColor) {
+                secondaryRanges->back().end = idx - 1;
+            }
+
+            // We are starting a range. Which range?
+            // note: encode the x offset without the final 1 pixel border.
+            if (color == kPrimaryColor) {
+                primaryRanges->push_back(Range(idx - 1, length - 2));
+            } else if (color == kSecondaryColor) {
+                secondaryRanges->push_back(Range(idx - 1, length - 2));
+            }
+            lastColor = color;
+        }
+    }
+    return true;
+}
+
+/**
+ * Iterates over a row in an image. Implements the templated ImageLine interface.
+ */
+class HorizontalImageLine {
+public:
+    explicit HorizontalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
+                                 int32_t length) :
+            mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {
+    }
+
+    inline int32_t getLength() const {
+        return mLength;
+    }
+
+    inline uint32_t getColor(int32_t idx) const {
+        return NinePatch::packRGBA(mRows[mYOffset] + (idx + mXOffset) * 4);
+    }
+
+private:
+    uint8_t** mRows;
+    int32_t mXOffset, mYOffset, mLength;
+
+    DISALLOW_COPY_AND_ASSIGN(HorizontalImageLine);
+};
+
+/**
+ * Iterates over a column in an image. Implements the templated ImageLine interface.
+ */
+class VerticalImageLine {
+public:
+    explicit VerticalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
+                               int32_t length) :
+            mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mLength(length) {
+    }
+
+    inline int32_t getLength() const {
+        return mLength;
+    }
+
+    inline uint32_t getColor(int32_t idx) const {
+        return NinePatch::packRGBA(mRows[mYOffset + idx] + (mXOffset * 4));
+    }
+
+private:
+    uint8_t** mRows;
+    int32_t mXOffset, mYOffset, mLength;
+
+    DISALLOW_COPY_AND_ASSIGN(VerticalImageLine);
+};
+
+class DiagonalImageLine {
+public:
+    explicit DiagonalImageLine(uint8_t** rows, int32_t xOffset, int32_t yOffset,
+                               int32_t xStep, int32_t yStep, int32_t length) :
+            mRows(rows), mXOffset(xOffset), mYOffset(yOffset), mXStep(xStep), mYStep(yStep),
+            mLength(length) {
+    }
+
+    inline int32_t getLength() const {
+        return mLength;
+    }
+
+    inline uint32_t getColor(int32_t idx) const {
+        return NinePatch::packRGBA(
+                mRows[mYOffset + (idx * mYStep)] + ((idx + mXOffset) * mXStep) * 4);
+    }
+
+private:
+    uint8_t** mRows;
+    int32_t mXOffset, mYOffset, mXStep, mYStep, mLength;
+
+    DISALLOW_COPY_AND_ASSIGN(DiagonalImageLine);
+};
+
+class TransparentNeutralColorValidator : public ColorValidator {
+public:
+    bool isNeutralColor(uint32_t color) const override {
+        return getAlpha(color) == 0;
+    }
+};
+
+class WhiteNeutralColorValidator : public ColorValidator {
+public:
+    bool isNeutralColor(uint32_t color) const override {
+        return color == kColorOpaqueWhite;
+    }
+};
+
+inline static uint32_t getAlpha(uint32_t color) {
+    return (color & 0xff000000u) >> 24;
+}
+
+static bool populateBounds(const std::vector<Range>& padding,
+                           const std::vector<Range>& layoutBounds,
+                           const std::vector<Range>& stretchRegions,
+                           const int32_t length,
+                           int32_t* paddingStart, int32_t* paddingEnd,
+                           int32_t* layoutStart, int32_t* layoutEnd,
+                           const StringPiece& edgeName,
+                           std::string* err) {
+    if (padding.size() > 1) {
+        std::stringstream errStream;
+        errStream << "too many padding sections on " << edgeName << " border";
+        *err = errStream.str();
+        return false;
+    }
+
+    *paddingStart = 0;
+    *paddingEnd = 0;
+    if (!padding.empty()) {
+        const Range& range = padding.front();
+        *paddingStart = range.start;
+        *paddingEnd = length - range.end;
+    } else if (!stretchRegions.empty()) {
+        // No padding was defined. Compute the padding from the first and last
+        // stretch regions.
+        *paddingStart = stretchRegions.front().start;
+        *paddingEnd = length - stretchRegions.back().end;
+    }
+
+    if (layoutBounds.size() > 2) {
+        std::stringstream errStream;
+        errStream << "too many layout bounds sections on " << edgeName << " border";
+        *err = errStream.str();
+        return false;
+    }
+
+    *layoutStart = 0;
+    *layoutEnd = 0;
+    if (layoutBounds.size() >= 1) {
+        const Range& range = layoutBounds.front();
+        // If there is only one layout bound segment, it might not start at 0, but then it should
+        // end at length.
+        if (range.start != 0 && range.end != length) {
+            std::stringstream errStream;
+            errStream << "layout bounds on " << edgeName << " border must start at edge";
+            *err = errStream.str();
+            return false;
+        }
+        *layoutStart = range.end;
+
+        if (layoutBounds.size() >= 2) {
+            const Range& range = layoutBounds.back();
+            if (range.end != length) {
+                std::stringstream errStream;
+                errStream << "layout bounds on " << edgeName << " border must start at edge";
+                *err = errStream.str();
+                return false;
+            }
+            *layoutEnd = length - range.start;
+        }
+    }
+    return true;
+}
+
+static int32_t calculateSegmentCount(const std::vector<Range>& stretchRegions, int32_t length) {
+    if (stretchRegions.size() == 0) {
+        return 0;
+    }
+
+    const bool startIsFixed = stretchRegions.front().start != 0;
+    const bool endIsFixed = stretchRegions.back().end != length;
+    int32_t modifier = 0;
+    if (startIsFixed && endIsFixed) {
+        modifier = 1;
+    } else if (!startIsFixed && !endIsFixed) {
+        modifier = -1;
+    }
+    return static_cast<int32_t>(stretchRegions.size()) * 2 + modifier;
+}
+
+static uint32_t getRegionColor(uint8_t** rows, const Bounds& region) {
+    // Sample the first pixel to compare against.
+    const uint32_t expectedColor = NinePatch::packRGBA(rows[region.top] + region.left * 4);
+    for (int32_t y = region.top; y < region.bottom; y++) {
+        const uint8_t* row = rows[y];
+        for (int32_t x = region.left; x < region.right; x++) {
+            const uint32_t color = NinePatch::packRGBA(row + x * 4);
+            if (getAlpha(color) == 0) {
+                // The color is transparent.
+                // If the expectedColor is not transparent, NO_COLOR.
+                if (getAlpha(expectedColor) != 0) {
+                    return android::Res_png_9patch::NO_COLOR;
+                }
+            } else if (color != expectedColor) {
+                return android::Res_png_9patch::NO_COLOR;
+            }
+        }
+    }
+
+    if (getAlpha(expectedColor) == 0) {
+        return android::Res_png_9patch::TRANSPARENT_COLOR;
+    }
+    return expectedColor;
+}
+
+// Fills outColors with each 9-patch section's colour. If the whole section is transparent,
+// it gets the special TRANSPARENT colour. If the whole section is the same colour, it is assigned
+// that colour. Otherwise it gets the special NO_COLOR colour.
+//
+// Note that the rows contain the 9-patch 1px border, and the indices in the stretch regions are
+// already offset to exclude the border. This means that each time the rows are accessed,
+// the indices must be offset by 1.
+//
+// width and height also include the 9-patch 1px border.
+static void calculateRegionColors(uint8_t** rows,
+                                  const std::vector<Range>& horizontalStretchRegions,
+                                  const std::vector<Range>& verticalStretchRegions,
+                                  const int32_t width, const int32_t height,
+                                  std::vector<uint32_t>* outColors) {
+    int32_t nextTop = 0;
+    Bounds bounds;
+    auto rowIter = verticalStretchRegions.begin();
+    while (nextTop != height) {
+        if (rowIter != verticalStretchRegions.end()) {
+            if (nextTop != rowIter->start) {
+                // This is a fixed segment.
+                // Offset the bounds by 1 to accommodate the border.
+                bounds.top = nextTop + 1;
+                bounds.bottom = rowIter->start + 1;
+                nextTop = rowIter->start;
+            } else {
+                // This is a stretchy segment.
+                // Offset the bounds by 1 to accommodate the border.
+                bounds.top = rowIter->start + 1;
+                bounds.bottom = rowIter->end + 1;
+                nextTop = rowIter->end;
+                ++rowIter;
+            }
+        } else {
+            // This is the end, fixed section.
+            // Offset the bounds by 1 to accommodate the border.
+            bounds.top = nextTop + 1;
+            bounds.bottom = height + 1;
+            nextTop = height;
+         }
+
+        int32_t nextLeft = 0;
+        auto colIter = horizontalStretchRegions.begin();
+        while (nextLeft != width) {
+            if (colIter != horizontalStretchRegions.end()) {
+                if (nextLeft != colIter->start) {
+                    // This is a fixed segment.
+                    // Offset the bounds by 1 to accommodate the border.
+                    bounds.left = nextLeft + 1;
+                    bounds.right = colIter->start + 1;
+                    nextLeft = colIter->start;
+                } else {
+                    // This is a stretchy segment.
+                    // Offset the bounds by 1 to accommodate the border.
+                    bounds.left = colIter->start + 1;
+                    bounds.right = colIter->end + 1;
+                    nextLeft = colIter->end;
+                    ++colIter;
+                }
+            } else {
+                // This is the end, fixed section.
+                // Offset the bounds by 1 to accommodate the border.
+                bounds.left = nextLeft + 1;
+                bounds.right = width + 1;
+                nextLeft = width;
+            }
+            outColors->push_back(getRegionColor(rows, bounds));
+        }
+    }
+}
+
+// Calculates the insets of a row/column of pixels based on where the largest alpha value begins
+// (on both sides).
+template <typename ImageLine>
+static void findOutlineInsets(const ImageLine* imageLine, int32_t* outStart, int32_t* outEnd) {
+    *outStart = 0;
+    *outEnd = 0;
+
+    const int32_t length = imageLine->getLength();
+    if (length < 3) {
+        return;
+    }
+
+    // If the length is odd, we want both sides to process the center pixel,
+    // so we use two different midpoints (to account for < and <= in the different loops).
+    const int32_t mid2 = length / 2;
+    const int32_t mid1 = mid2 + (length % 2);
+
+    uint32_t maxAlpha = 0;
+    for (int32_t i = 0; i < mid1 && maxAlpha != 0xff; i++) {
+        uint32_t alpha = getAlpha(imageLine->getColor(i));
+        if (alpha > maxAlpha) {
+            maxAlpha = alpha;
+            *outStart = i;
+        }
+    }
+
+    maxAlpha = 0;
+    for (int32_t i = length - 1; i >= mid2 && maxAlpha != 0xff; i--) {
+        uint32_t alpha = getAlpha(imageLine->getColor(i));
+        if (alpha > maxAlpha) {
+            maxAlpha = alpha;
+            *outEnd = length - (i + 1);
+        }
+    }
+    return;
+}
+
+template <typename ImageLine>
+static uint32_t findMaxAlpha(const ImageLine* imageLine) {
+    const int32_t length = imageLine->getLength();
+    uint32_t maxAlpha = 0;
+    for (int32_t idx = 0; idx < length && maxAlpha != 0xff; idx++) {
+        uint32_t alpha = getAlpha(imageLine->getColor(idx));
+        if (alpha > maxAlpha) {
+            maxAlpha = alpha;
+        }
+    }
+    return maxAlpha;
+}
+
+// Pack the pixels in as 0xAARRGGBB (as 9-patch expects it).
+uint32_t NinePatch::packRGBA(const uint8_t* pixel) {
+    return (pixel[3] << 24) | (pixel[0] << 16) | (pixel[1] << 8) | pixel[2];
+}
+
+std::unique_ptr<NinePatch> NinePatch::create(uint8_t** rows,
+                                             const int32_t width, const int32_t height,
+                                             std::string* err) {
+    if (width < 3 || height < 3) {
+        *err = "image must be at least 3x3 (1x1 image with 1 pixel border)";
+        return {};
+    }
+
+    std::vector<Range> horizontalPadding;
+    std::vector<Range> horizontalOpticalBounds;
+    std::vector<Range> verticalPadding;
+    std::vector<Range> verticalOpticalBounds;
+    std::vector<Range> unexpectedRanges;
+    std::unique_ptr<ColorValidator> colorValidator;
+
+    if (rows[0][3] == 0) {
+        colorValidator = util::make_unique<TransparentNeutralColorValidator>();
+    } else if (packRGBA(rows[0]) == kColorOpaqueWhite) {
+        colorValidator = util::make_unique<WhiteNeutralColorValidator>();
+    } else {
+        *err = "top-left corner pixel must be either opaque white or transparent";
+        return {};
+    }
+
+    // Private constructor, can't use make_unique.
+    auto ninePatch = std::unique_ptr<NinePatch>(new NinePatch());
+
+    HorizontalImageLine topRow(rows, 0, 0, width);
+    if (!fillRanges(&topRow, colorValidator.get(), &ninePatch->horizontalStretchRegions,
+                    &unexpectedRanges, err)) {
+        return {};
+    }
+
+    if (!unexpectedRanges.empty()) {
+        const Range& range = unexpectedRanges[0];
+        std::stringstream errStream;
+        errStream << "found unexpected optical bounds (red pixel) on top border "
+                << "at x=" << range.start + 1;
+        *err = errStream.str();
+        return {};
+    }
+
+    VerticalImageLine leftCol(rows, 0, 0, height);
+    if (!fillRanges(&leftCol, colorValidator.get(), &ninePatch->verticalStretchRegions,
+                    &unexpectedRanges, err)) {
+        return {};
+    }
+
+    if (!unexpectedRanges.empty()) {
+        const Range& range = unexpectedRanges[0];
+        std::stringstream errStream;
+        errStream << "found unexpected optical bounds (red pixel) on left border "
+                << "at y=" << range.start + 1;
+        return {};
+    }
+
+    HorizontalImageLine bottomRow(rows, 0, height - 1, width);
+    if (!fillRanges(&bottomRow, colorValidator.get(), &horizontalPadding,
+                    &horizontalOpticalBounds, err)) {
+        return {};
+    }
+
+    if (!populateBounds(horizontalPadding, horizontalOpticalBounds,
+                        ninePatch->horizontalStretchRegions, width - 2,
+                        &ninePatch->padding.left, &ninePatch->padding.right,
+                        &ninePatch->layoutBounds.left, &ninePatch->layoutBounds.right,
+                        "bottom", err)) {
+        return {};
+    }
+
+    VerticalImageLine rightCol(rows, width - 1, 0, height);
+    if (!fillRanges(&rightCol, colorValidator.get(), &verticalPadding,
+                    &verticalOpticalBounds, err)) {
+        return {};
+    }
+
+    if (!populateBounds(verticalPadding, verticalOpticalBounds,
+                        ninePatch->verticalStretchRegions, height - 2,
+                        &ninePatch->padding.top, &ninePatch->padding.bottom,
+                        &ninePatch->layoutBounds.top, &ninePatch->layoutBounds.bottom,
+                        "right", err)) {
+        return {};
+    }
+
+    // Fill the region colors of the 9-patch.
+    const int32_t numRows = calculateSegmentCount(ninePatch->horizontalStretchRegions, width - 2);
+    const int32_t numCols = calculateSegmentCount(ninePatch->verticalStretchRegions, height - 2);
+    if ((int64_t) numRows * (int64_t) numCols > 0x7f) {
+        *err = "too many regions in 9-patch";
+        return {};
+    }
+
+    ninePatch->regionColors.reserve(numRows * numCols);
+    calculateRegionColors(rows, ninePatch->horizontalStretchRegions,
+                          ninePatch->verticalStretchRegions,
+                          width - 2, height - 2,
+                          &ninePatch->regionColors);
+
+    // Compute the outline based on opacity.
+
+    // Find left and right extent of 9-patch content on center row.
+    HorizontalImageLine midRow(rows, 1, height / 2, width - 2);
+    findOutlineInsets(&midRow, &ninePatch->outline.left, &ninePatch->outline.right);
+
+    // Find top and bottom extent of 9-patch content on center column.
+    VerticalImageLine midCol(rows, width / 2, 1, height - 2);
+    findOutlineInsets(&midCol, &ninePatch->outline.top, &ninePatch->outline.bottom);
+
+    const int32_t outlineWidth = (width - 2) - ninePatch->outline.left - ninePatch->outline.right;
+    const int32_t outlineHeight = (height - 2) - ninePatch->outline.top - ninePatch->outline.bottom;
+
+    // Find the largest alpha value within the outline area.
+    HorizontalImageLine outlineMidRow(rows,
+                                      1 + ninePatch->outline.left,
+                                      1 + ninePatch->outline.top + (outlineHeight / 2),
+                                      outlineWidth);
+    VerticalImageLine outlineMidCol(rows,
+                                    1 + ninePatch->outline.left + (outlineWidth / 2),
+                                    1 + ninePatch->outline.top,
+                                    outlineHeight);
+    ninePatch->outlineAlpha = std::max(findMaxAlpha(&outlineMidRow), findMaxAlpha(&outlineMidCol));
+
+    // Assuming the image is a round rect, compute the radius by marching
+    // diagonally from the top left corner towards the center.
+    DiagonalImageLine diagonal(rows, 1 + ninePatch->outline.left, 1 + ninePatch->outline.top,
+                               1, 1, std::min(outlineWidth, outlineHeight));
+    int32_t topLeft, bottomRight;
+    findOutlineInsets(&diagonal, &topLeft, &bottomRight);
+
+    /* Determine source radius based upon inset:
+     *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r
+     *     sqrt(2) * r = sqrt(2) * i + r
+     *     (sqrt(2) - 1) * r = sqrt(2) * i
+     *     r = sqrt(2) / (sqrt(2) - 1) * i
+     */
+    ninePatch->outlineRadius = 3.4142f * topLeft;
+    return ninePatch;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::serializeBase(size_t* outLen) const {
+    android::Res_png_9patch data;
+    data.numXDivs = static_cast<uint8_t>(horizontalStretchRegions.size()) * 2;
+    data.numYDivs = static_cast<uint8_t>(verticalStretchRegions.size()) * 2;
+    data.numColors = static_cast<uint8_t>(regionColors.size());
+    data.paddingLeft = padding.left;
+    data.paddingRight = padding.right;
+    data.paddingTop = padding.top;
+    data.paddingBottom = padding.bottom;
+
+    auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[data.serializedSize()]);
+    android::Res_png_9patch::serialize(data,
+                                       (const int32_t*) horizontalStretchRegions.data(),
+                                       (const int32_t*) verticalStretchRegions.data(),
+                                       regionColors.data(),
+                                       buffer.get());
+    *outLen = data.serializedSize();
+    return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::serializeLayoutBounds(size_t* outLen) const {
+    size_t chunkLen = sizeof(uint32_t) * 4;
+    auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]);
+    uint8_t* cursor = buffer.get();
+
+    memcpy(cursor, &layoutBounds.left, sizeof(layoutBounds.left));
+    cursor += sizeof(layoutBounds.left);
+
+    memcpy(cursor, &layoutBounds.top, sizeof(layoutBounds.top));
+    cursor += sizeof(layoutBounds.top);
+
+    memcpy(cursor, &layoutBounds.right, sizeof(layoutBounds.right));
+    cursor += sizeof(layoutBounds.right);
+
+    memcpy(cursor, &layoutBounds.bottom, sizeof(layoutBounds.bottom));
+    cursor += sizeof(layoutBounds.bottom);
+
+    *outLen = chunkLen;
+    return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::serializeRoundedRectOutline(size_t* outLen) const {
+    size_t chunkLen = sizeof(uint32_t) * 6;
+    auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunkLen]);
+    uint8_t* cursor = buffer.get();
+
+    memcpy(cursor, &outline.left, sizeof(outline.left));
+    cursor += sizeof(outline.left);
+
+    memcpy(cursor, &outline.top, sizeof(outline.top));
+    cursor += sizeof(outline.top);
+
+    memcpy(cursor, &outline.right, sizeof(outline.right));
+    cursor += sizeof(outline.right);
+
+    memcpy(cursor, &outline.bottom, sizeof(outline.bottom));
+    cursor += sizeof(outline.bottom);
+
+    *((float*) cursor) = outlineRadius;
+    cursor += sizeof(outlineRadius);
+
+    *((uint32_t*) cursor) = outlineAlpha;
+
+    *outLen = chunkLen;
+    return buffer;
+}
+
+::std::ostream& operator<<(::std::ostream& out, const Range& range) {
+    return out << "[" << range.start << ", " << range.end << ")";
+}
+
+::std::ostream& operator<<(::std::ostream& out, const Bounds& bounds) {
+    return out << "l=" << bounds.left
+            << " t=" << bounds.top
+            << " r=" << bounds.right
+            << " b=" << bounds.bottom;
+}
+
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& ninePatch) {
+    return out << "padding: " << ninePatch.padding
+            << ", bounds: " << ninePatch.layoutBounds
+            << ", outline: " << ninePatch.outline
+            << " rad=" << ninePatch.outlineRadius
+            << " alpha=" << ninePatch.outlineAlpha;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/compile/NinePatch_test.cpp b/tools/aapt2/compile/NinePatch_test.cpp
new file mode 100644
index 0000000..ac4ee02
--- /dev/null
+++ b/tools/aapt2/compile/NinePatch_test.cpp
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compile/Image.h"
+#include "test/Test.h"
+
+namespace aapt {
+
+// Pixels are in RGBA_8888 packing.
+
+#define RED   "\xff\x00\x00\xff"
+#define BLUE  "\x00\x00\xff\xff"
+#define GREEN "\xff\x00\x00\xff"
+#define GR_70 "\xff\x00\x00\xb3"
+#define GR_50 "\xff\x00\x00\x80"
+#define GR_20 "\xff\x00\x00\x33"
+#define BLACK "\x00\x00\x00\xff"
+#define WHITE "\xff\xff\xff\xff"
+#define TRANS "\x00\x00\x00\x00"
+
+static uint8_t* k2x2[] = {
+        (uint8_t*) WHITE WHITE,
+        (uint8_t*) WHITE WHITE,
+};
+
+static uint8_t* kMixedNeutralColor3x3[] = {
+        (uint8_t*) WHITE BLACK TRANS,
+        (uint8_t*) TRANS RED   TRANS,
+        (uint8_t*) WHITE WHITE WHITE,
+};
+
+static uint8_t* kTransparentNeutralColor3x3[] = {
+        (uint8_t*) TRANS BLACK TRANS,
+        (uint8_t*) BLACK RED   BLACK,
+        (uint8_t*) TRANS BLACK TRANS,
+};
+
+static uint8_t* kSingleStretch7x6[] = {
+        (uint8_t*) WHITE WHITE BLACK BLACK BLACK WHITE WHITE,
+        (uint8_t*) WHITE RED   RED   RED   RED   RED   WHITE,
+        (uint8_t*) BLACK RED   RED   RED   RED   RED   WHITE,
+        (uint8_t*) BLACK RED   RED   RED   RED   RED   WHITE,
+        (uint8_t*) WHITE RED   RED   RED   RED   RED   WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kMultipleStretch10x7[] = {
+        (uint8_t*) WHITE WHITE BLACK WHITE BLACK BLACK WHITE BLACK WHITE WHITE,
+        (uint8_t*) BLACK RED   BLUE  RED   BLUE  BLUE  RED   BLUE  RED   WHITE,
+        (uint8_t*) BLACK RED   BLUE  RED   BLUE  BLUE  RED   BLUE  RED   WHITE,
+        (uint8_t*) WHITE RED   BLUE  RED   BLUE  BLUE  RED   BLUE  RED   WHITE,
+        (uint8_t*) BLACK RED   BLUE  RED   BLUE  BLUE  RED   BLUE  RED   WHITE,
+        (uint8_t*) BLACK RED   BLUE  RED   BLUE  BLUE  RED   BLUE  RED   WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kPadding6x5[] = {
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE BLACK,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE BLACK BLACK WHITE WHITE,
+};
+
+static uint8_t* kLayoutBoundsWrongEdge3x3[] = {
+        (uint8_t*) WHITE RED   WHITE,
+        (uint8_t*) RED   WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE,
+};
+
+static uint8_t* kLayoutBoundsNotEdgeAligned5x5[] = {
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE RED   WHITE WHITE,
+};
+
+static uint8_t* kLayoutBounds5x5[] = {
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE RED   WHITE RED   WHITE,
+};
+
+static uint8_t* kAsymmetricLayoutBounds5x5[] = {
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE RED   WHITE WHITE WHITE,
+};
+
+static uint8_t* kPaddingAndLayoutBounds5x5[] = {
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE WHITE WHITE WHITE BLACK,
+        (uint8_t*) WHITE WHITE WHITE WHITE RED,
+        (uint8_t*) WHITE RED   BLACK RED   WHITE,
+};
+
+static uint8_t* kColorfulImage5x5[] = {
+        (uint8_t*) WHITE BLACK WHITE BLACK WHITE,
+        (uint8_t*) BLACK RED   BLUE  GREEN WHITE,
+        (uint8_t*) BLACK RED   GREEN GREEN WHITE,
+        (uint8_t*) WHITE TRANS BLUE  GREEN WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kOutlineOpaque10x10[] = {
+        (uint8_t*) WHITE BLACK BLACK BLACK BLACK BLACK BLACK BLACK BLACK WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GREEN GREEN GREEN GREEN TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GREEN GREEN GREEN GREEN TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GREEN GREEN GREEN GREEN TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GREEN GREEN GREEN GREEN TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kOutlineTranslucent10x10[] = {
+        (uint8_t*) WHITE BLACK BLACK BLACK BLACK BLACK BLACK BLACK BLACK WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GR_20 GR_20 GR_20 GR_20 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GR_50 GR_50 GR_50 GR_50 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS GR_20 GR_50 GR_70 GR_70 GR_50 GR_20 TRANS WHITE,
+        (uint8_t*) WHITE TRANS GR_20 GR_50 GR_70 GR_70 GR_50 GR_20 TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GR_50 GR_50 GR_50 GR_50 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS GR_20 GR_20 GR_20 GR_20 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kOutlineOffsetTranslucent12x10[] = {
+        (uint8_t*) WHITE WHITE WHITE BLACK BLACK BLACK BLACK BLACK BLACK BLACK BLACK WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS GR_20 GR_20 GR_20 GR_20 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS GR_50 GR_50 GR_50 GR_50 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS GR_20 GR_50 GR_70 GR_70 GR_50 GR_20 TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS GR_20 GR_50 GR_70 GR_70 GR_50 GR_20 TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS GR_50 GR_50 GR_50 GR_50 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS GR_20 GR_20 GR_20 GR_20 TRANS TRANS WHITE,
+        (uint8_t*) WHITE TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS TRANS WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE WHITE,
+};
+
+static uint8_t* kOutlineRadius5x5[] = {
+        (uint8_t*) WHITE BLACK BLACK BLACK WHITE,
+        (uint8_t*) BLACK TRANS GREEN TRANS WHITE,
+        (uint8_t*) BLACK GREEN GREEN GREEN WHITE,
+        (uint8_t*) BLACK TRANS GREEN TRANS WHITE,
+        (uint8_t*) WHITE WHITE WHITE WHITE WHITE,
+};
+
+TEST(NinePatchTest, Minimum3x3) {
+    std::string err;
+    EXPECT_EQ(nullptr, NinePatch::create(k2x2, 2, 2, &err));
+    EXPECT_FALSE(err.empty());
+}
+
+TEST(NinePatchTest, MixedNeutralColors) {
+    std::string err;
+    EXPECT_EQ(nullptr, NinePatch::create(kMixedNeutralColor3x3, 3, 3, &err));
+    EXPECT_FALSE(err.empty());
+}
+
+TEST(NinePatchTest, TransparentNeutralColor) {
+    std::string err;
+    EXPECT_NE(nullptr, NinePatch::create(kTransparentNeutralColor3x3, 3, 3, &err));
+}
+
+TEST(NinePatchTest, SingleStretchRegion) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kSingleStretch7x6, 7, 6, &err);
+    ASSERT_NE(nullptr, ninePatch);
+
+    ASSERT_EQ(1u, ninePatch->horizontalStretchRegions.size());
+    ASSERT_EQ(1u, ninePatch->verticalStretchRegions.size());
+
+    EXPECT_EQ(Range(1, 4), ninePatch->horizontalStretchRegions.front());
+    EXPECT_EQ(Range(1, 3), ninePatch->verticalStretchRegions.front());
+}
+
+TEST(NinePatchTest, MultipleStretchRegions) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kMultipleStretch10x7, 10, 7, &err);
+    ASSERT_NE(nullptr, ninePatch);
+
+    ASSERT_EQ(3u, ninePatch->horizontalStretchRegions.size());
+    ASSERT_EQ(2u, ninePatch->verticalStretchRegions.size());
+
+    EXPECT_EQ(Range(1, 2), ninePatch->horizontalStretchRegions[0]);
+    EXPECT_EQ(Range(3, 5), ninePatch->horizontalStretchRegions[1]);
+    EXPECT_EQ(Range(6, 7), ninePatch->horizontalStretchRegions[2]);
+
+    EXPECT_EQ(Range(0, 2), ninePatch->verticalStretchRegions[0]);
+    EXPECT_EQ(Range(3, 5), ninePatch->verticalStretchRegions[1]);
+}
+
+TEST(NinePatchTest, InferPaddingFromStretchRegions) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kMultipleStretch10x7, 10, 7, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(1, 0, 1, 0), ninePatch->padding);
+}
+
+TEST(NinePatchTest, Padding) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kPadding6x5, 6, 5, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding);
+}
+
+TEST(NinePatchTest, LayoutBoundsAreOnWrongEdge) {
+    std::string err;
+    EXPECT_EQ(nullptr, NinePatch::create(kLayoutBoundsWrongEdge3x3, 3, 3, &err));
+    EXPECT_FALSE(err.empty());
+}
+
+TEST(NinePatchTest, LayoutBoundsMustTouchEdges) {
+    std::string err;
+    EXPECT_EQ(nullptr, NinePatch::create(kLayoutBoundsNotEdgeAligned5x5, 5, 5, &err));
+    EXPECT_FALSE(err.empty());
+}
+
+TEST(NinePatchTest, LayoutBounds) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kLayoutBounds5x5, 5, 5, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds);
+
+    ninePatch = NinePatch::create(kAsymmetricLayoutBounds5x5, 5, 5, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(1, 1, 0, 0), ninePatch->layoutBounds);
+}
+
+TEST(NinePatchTest, PaddingAndLayoutBounds) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kPaddingAndLayoutBounds5x5, 5, 5,
+                                                             &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->padding);
+    EXPECT_EQ(Bounds(1, 1, 1, 1), ninePatch->layoutBounds);
+}
+
+TEST(NinePatchTest, RegionColorsAreCorrect) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kColorfulImage5x5, 5, 5, &err);
+    ASSERT_NE(nullptr, ninePatch);
+
+    std::vector<uint32_t> expectedColors = {
+            NinePatch::packRGBA((uint8_t*) RED),
+            (uint32_t) android::Res_png_9patch::NO_COLOR,
+            NinePatch::packRGBA((uint8_t*) GREEN),
+            (uint32_t) android::Res_png_9patch::TRANSPARENT_COLOR,
+            NinePatch::packRGBA((uint8_t*) BLUE),
+            NinePatch::packRGBA((uint8_t*) GREEN),
+    };
+    EXPECT_EQ(expectedColors, ninePatch->regionColors);
+}
+
+TEST(NinePatchTest, OutlineFromOpaqueImage) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kOutlineOpaque10x10, 10, 10, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(2, 2, 2, 2), ninePatch->outline);
+    EXPECT_EQ(0x000000ffu, ninePatch->outlineAlpha);
+    EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+}
+
+TEST(NinePatchTest, OutlineFromTranslucentImage) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kOutlineTranslucent10x10, 10, 10,
+                                                             &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(3, 3, 3, 3), ninePatch->outline);
+    EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha);
+    EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+}
+
+TEST(NinePatchTest, OutlineFromOffCenterImage) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kOutlineOffsetTranslucent12x10, 12, 10,
+                                                             &err);
+    ASSERT_NE(nullptr, ninePatch);
+
+    // TODO(adamlesinski): The old AAPT algorithm searches from the outside to the middle
+    // for each inset. If the outline is shifted, the search may not find a closer bounds.
+    // This check should be:
+    //   EXPECT_EQ(Bounds(5, 3, 3, 3), ninePatch->outline);
+    // but until I know what behaviour I'm breaking, I will leave it at the incorrect:
+    EXPECT_EQ(Bounds(4, 3, 3, 3), ninePatch->outline);
+
+    EXPECT_EQ(0x000000b3u, ninePatch->outlineAlpha);
+    EXPECT_EQ(0.0f, ninePatch->outlineRadius);
+}
+
+TEST(NinePatchTest, OutlineRadius) {
+    std::string err;
+    std::unique_ptr<NinePatch> ninePatch = NinePatch::create(kOutlineRadius5x5, 5, 5, &err);
+    ASSERT_NE(nullptr, ninePatch);
+    EXPECT_EQ(Bounds(0, 0, 0, 0), ninePatch->outline);
+    EXPECT_EQ(3.4142f, ninePatch->outlineRadius);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/compile/Png.h b/tools/aapt2/compile/Png.h
index f835b06e..4a15d95 100644
--- a/tools/aapt2/compile/Png.h
+++ b/tools/aapt2/compile/Png.h
@@ -17,10 +17,14 @@
 #ifndef AAPT_PNG_H
 #define AAPT_PNG_H
 
-#include "util/BigBuffer.h"
 #include "Diagnostics.h"
 #include "Source.h"
+#include "compile/Image.h"
+#include "io/Io.h"
+#include "process/IResourceTableConsumer.h"
+#include "util/BigBuffer.h"
 
+#include <android-base/macros.h>
 #include <iostream>
 #include <string>
 
@@ -40,8 +44,51 @@
 
 private:
     IDiagnostics* mDiag;
+
+    DISALLOW_COPY_AND_ASSIGN(Png);
 };
 
+/**
+ * An InputStream that filters out unimportant PNG chunks.
+ */
+class PngChunkFilter : public io::InputStream {
+public:
+    explicit PngChunkFilter(const StringPiece& data);
+
+    bool Next(const void** buffer, int* len) override;
+    void BackUp(int count) override;
+    bool Skip(int count) override;
+
+    int64_t ByteCount() const override {
+        return static_cast<int64_t>(mWindowStart);
+    }
+
+    bool HadError() const override {
+        return mError;
+    }
+
+private:
+    bool consumeWindow(const void** buffer, int* len);
+
+    StringPiece mData;
+    size_t mWindowStart = 0;
+    size_t mWindowEnd = 0;
+    bool mError = false;
+
+    DISALLOW_COPY_AND_ASSIGN(PngChunkFilter);
+};
+
+/**
+ * Reads a PNG from the InputStream into memory as an RGBA Image.
+ */
+std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in);
+
+/**
+ * Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream as a PNG.
+ */
+bool writePng(IAaptContext* context, const Image* image, const NinePatch* ninePatch,
+              io::OutputStream* out, const PngOptions& options);
+
 } // namespace aapt
 
 #endif // AAPT_PNG_H
diff --git a/tools/aapt2/compile/PngChunkFilter.cpp b/tools/aapt2/compile/PngChunkFilter.cpp
new file mode 100644
index 0000000..70a881f
--- /dev/null
+++ b/tools/aapt2/compile/PngChunkFilter.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compile/Png.h"
+#include "io/Io.h"
+#include "util/StringPiece.h"
+
+namespace aapt {
+
+static constexpr const char* kPngSignature = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a";
+
+// Useful helper function that encodes individual bytes into a uint32
+// at compile time.
+constexpr uint32_t u32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+    return (((uint32_t) a) << 24)
+            | (((uint32_t) b) << 16)
+            | (((uint32_t) c) << 8)
+            | ((uint32_t) d);
+}
+
+// Whitelist of PNG chunk types that we want to keep in the resulting PNG.
+enum PngChunkTypes {
+    kPngChunkIHDR = u32(73, 72, 68, 82),
+    kPngChunkIDAT = u32(73, 68, 65, 84),
+    kPngChunkIEND = u32(73, 69, 78, 68),
+    kPngChunkPLTE = u32(80, 76, 84, 69),
+    kPngChunktRNS = u32(116, 82, 78, 83),
+    kPngChunksRGB = u32(115, 82, 71, 66),
+};
+
+static uint32_t peek32LE(const char* data) {
+    uint32_t word = ((uint32_t) data[0]) & 0x000000ff;
+    word <<= 8;
+    word |= ((uint32_t) data[1]) & 0x000000ff;
+    word <<= 8;
+    word |= ((uint32_t) data[2]) & 0x000000ff;
+    word <<= 8;
+    word |= ((uint32_t) data[3]) & 0x000000ff;
+    return word;
+}
+
+static bool isPngChunkWhitelisted(uint32_t type) {
+    switch (type) {
+    case kPngChunkIHDR:
+    case kPngChunkIDAT:
+    case kPngChunkIEND:
+    case kPngChunkPLTE:
+    case kPngChunktRNS:
+    case kPngChunksRGB:
+        return true;
+    default:
+        return false;
+    }
+}
+
+PngChunkFilter::PngChunkFilter(const StringPiece& data) : mData(data) {
+    if (util::stringStartsWith(mData, kPngSignature)) {
+        mWindowStart = 0;
+        mWindowEnd = strlen(kPngSignature);
+    } else {
+        mError = true;
+    }
+}
+
+bool PngChunkFilter::consumeWindow(const void** buffer, int* len) {
+    if (mWindowStart != mWindowEnd) {
+        // We have bytes to give from our window.
+        const int bytesRead = (int) (mWindowEnd - mWindowStart);
+        *buffer = mData.data() + mWindowStart;
+        *len = bytesRead;
+        mWindowStart = mWindowEnd;
+        return true;
+    }
+    return false;
+}
+
+bool PngChunkFilter::Next(const void** buffer, int* len) {
+    if (mError) {
+        return false;
+    }
+
+    // In case BackUp was called, we must consume the window.
+    if (consumeWindow(buffer, len)) {
+        return true;
+    }
+
+    // Advance the window as far as possible (until we meet a chunk that
+    // we want to strip).
+    while (mWindowEnd < mData.size()) {
+        // Chunk length (4 bytes) + type (4 bytes) + crc32 (4 bytes) = 12 bytes.
+        const size_t kMinChunkHeaderSize = 3 * sizeof(uint32_t);
+
+        // Is there enough room for a chunk header?
+        if (mData.size() - mWindowStart < kMinChunkHeaderSize) {
+            mError = true;
+            return false;
+        }
+
+        // Verify the chunk length.
+        const uint32_t chunkLen = peek32LE(mData.data() + mWindowEnd);
+        if (((uint64_t) chunkLen) + ((uint64_t) mWindowEnd) + sizeof(uint32_t) > mData.size()) {
+            // Overflow.
+            mError = true;
+            return false;
+        }
+
+        // Do we strip this chunk?
+        const uint32_t chunkType = peek32LE(mData.data() + mWindowEnd + sizeof(uint32_t));
+        if (isPngChunkWhitelisted(chunkType)) {
+            // Advance the window to include this chunk.
+            mWindowEnd += kMinChunkHeaderSize + chunkLen;
+        } else {
+            // We want to strip this chunk. If we accumulated a window,
+            // we must return the window now.
+            if (mWindowStart != mWindowEnd) {
+                break;
+            }
+
+            // The window is empty, so we can advance past this chunk
+            // and keep looking for the next good chunk,
+            mWindowEnd += kMinChunkHeaderSize + chunkLen;
+            mWindowStart = mWindowEnd;
+        }
+    }
+
+    if (consumeWindow(buffer, len)) {
+        return true;
+    }
+    return false;
+}
+
+void PngChunkFilter::BackUp(int count) {
+    if (mError) {
+        return;
+    }
+    mWindowStart -= count;
+}
+
+bool PngChunkFilter::Skip(int count) {
+    if (mError) {
+        return false;
+    }
+
+    const void* buffer;
+    int len;
+    while (count > 0) {
+        if (!Next(&buffer, &len)) {
+            return false;
+        }
+        if (len > count) {
+            BackUp(len - count);
+            count = 0;
+        } else {
+            count -= len;
+        }
+    }
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp
new file mode 100644
index 0000000..a2e3f4f
--- /dev/null
+++ b/tools/aapt2/compile/PngCrunch.cpp
@@ -0,0 +1,724 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compile/Png.h"
+
+#include <algorithm>
+#include <android-base/errors.h>
+#include <android-base/macros.h>
+#include <png.h>
+#include <unordered_map>
+#include <unordered_set>
+#include <zlib.h>
+
+namespace aapt {
+
+// Size in bytes of the PNG signature.
+constexpr size_t kPngSignatureSize = 8u;
+
+/**
+ * Custom deleter that destroys libpng read and info structs.
+ */
+class PngReadStructDeleter {
+public:
+    explicit PngReadStructDeleter(png_structp readPtr, png_infop infoPtr) :
+            mReadPtr(readPtr), mInfoPtr(infoPtr) {
+    }
+
+    ~PngReadStructDeleter() {
+        png_destroy_read_struct(&mReadPtr, &mInfoPtr, nullptr);
+    }
+
+private:
+    png_structp mReadPtr;
+    png_infop mInfoPtr;
+
+    DISALLOW_COPY_AND_ASSIGN(PngReadStructDeleter);
+};
+
+/**
+ * Custom deleter that destroys libpng write and info structs.
+ */
+class PngWriteStructDeleter {
+public:
+    explicit PngWriteStructDeleter(png_structp writePtr, png_infop infoPtr) :
+            mWritePtr(writePtr), mInfoPtr(infoPtr) {
+    }
+
+    ~PngWriteStructDeleter() {
+        png_destroy_write_struct(&mWritePtr, &mInfoPtr);
+    }
+
+private:
+    png_structp mWritePtr;
+    png_infop mInfoPtr;
+
+    DISALLOW_COPY_AND_ASSIGN(PngWriteStructDeleter);
+};
+
+// Custom warning logging method that uses IDiagnostics.
+static void logWarning(png_structp pngPtr, png_const_charp warningMsg) {
+    IDiagnostics* diag = (IDiagnostics*) png_get_error_ptr(pngPtr);
+    diag->warn(DiagMessage() << warningMsg);
+}
+
+// Custom error logging method that uses IDiagnostics.
+static void logError(png_structp pngPtr, png_const_charp errorMsg) {
+    IDiagnostics* diag = (IDiagnostics*) png_get_error_ptr(pngPtr);
+    diag->error(DiagMessage() << errorMsg);
+}
+
+static void readDataFromStream(png_structp pngPtr, png_bytep buffer, png_size_t len) {
+    io::InputStream* in = (io::InputStream*) png_get_io_ptr(pngPtr);
+
+    const void* inBuffer;
+    int inLen;
+    if (!in->Next(&inBuffer, &inLen)) {
+        if (in->HadError()) {
+            std::string err = in->GetError();
+            png_error(pngPtr, err.c_str());
+        }
+        return;
+    }
+
+    const size_t bytesRead = std::min(static_cast<size_t>(inLen), len);
+    memcpy(buffer, inBuffer, bytesRead);
+    if (bytesRead != static_cast<size_t>(inLen)) {
+        in->BackUp(inLen - static_cast<int>(bytesRead));
+    }
+}
+
+static void writeDataToStream(png_structp pngPtr, png_bytep buffer, png_size_t len) {
+    io::OutputStream* out = (io::OutputStream*) png_get_io_ptr(pngPtr);
+
+    void* outBuffer;
+    int outLen;
+    while (len > 0) {
+        if (!out->Next(&outBuffer, &outLen)) {
+            if (out->HadError()) {
+                std::string err = out->GetError();
+                png_error(pngPtr, err.c_str());
+            }
+            return;
+        }
+
+        const size_t bytesWritten = std::min(static_cast<size_t>(outLen), len);
+        memcpy(outBuffer, buffer, bytesWritten);
+
+        // Advance the input buffer.
+        buffer += bytesWritten;
+        len -= bytesWritten;
+
+        // Advance the output buffer.
+        outLen -= static_cast<int>(bytesWritten);
+    }
+
+    // If the entire output buffer wasn't used, backup.
+    if (outLen > 0) {
+        out->BackUp(outLen);
+    }
+}
+
+std::unique_ptr<Image> readPng(IAaptContext* context, io::InputStream* in) {
+    // Read the first 8 bytes of the file looking for the PNG signature.
+    // Bail early if it does not match.
+    const png_byte* signature;
+    int bufferSize;
+    if (!in->Next((const void**) &signature, &bufferSize)) {
+        context->getDiagnostics()->error(DiagMessage()
+                                         << android::base::SystemErrorCodeToString(errno));
+        return {};
+    }
+
+    if (static_cast<size_t>(bufferSize) < kPngSignatureSize
+            || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
+        context->getDiagnostics()->error(DiagMessage()
+                                         << "file signature does not match PNG signature");
+        return {};
+    }
+
+    // Start at the beginning of the first chunk.
+    in->BackUp(bufferSize - static_cast<int>(kPngSignatureSize));
+
+    // Create and initialize the png_struct with the default error and warning handlers.
+    // The header version is also passed in to ensure that this was built against the same
+    // version of libpng.
+    png_structp readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+    if (readPtr == nullptr) {
+        context->getDiagnostics()->error(DiagMessage()
+                                         << "failed to create libpng read png_struct");
+        return {};
+    }
+
+    // Create and initialize the memory for image header and data.
+    png_infop infoPtr = png_create_info_struct(readPtr);
+    if (infoPtr == nullptr) {
+        context->getDiagnostics()->error(DiagMessage() << "failed to create libpng read png_info");
+        png_destroy_read_struct(&readPtr, nullptr, nullptr);
+        return {};
+    }
+
+    // Automatically release PNG resources at end of scope.
+    PngReadStructDeleter pngReadDeleter(readPtr, infoPtr);
+
+    // libpng uses longjmp to jump to an error handling routine.
+    // setjmp will only return true if it was jumped to, aka there was
+    // an error.
+    if (setjmp(png_jmpbuf(readPtr))) {
+        return {};
+    }
+
+    // Handle warnings ourselves via IDiagnostics.
+    png_set_error_fn(readPtr, (png_voidp) context->getDiagnostics(), logError, logWarning);
+
+    // Set up the read functions which read from our custom data sources.
+    png_set_read_fn(readPtr, (png_voidp) in, readDataFromStream);
+
+    // Skip the signature that we already read.
+    png_set_sig_bytes(readPtr, kPngSignatureSize);
+
+    // Read the chunk headers.
+    png_read_info(readPtr, infoPtr);
+
+    // Extract image meta-data from the various chunk headers.
+    uint32_t width, height;
+    int bitDepth, colorType, interlaceMethod, compressionMethod, filterMethod;
+    png_get_IHDR(readPtr, infoPtr, &width, &height, &bitDepth, &colorType, &interlaceMethod,
+                 &compressionMethod, &filterMethod);
+
+    // When the image is read, expand it so that it is in RGBA 8888 format
+    // so that image handling is uniform.
+
+    if (colorType == PNG_COLOR_TYPE_PALETTE) {
+        png_set_palette_to_rgb(readPtr);
+    }
+
+    if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) {
+        png_set_expand_gray_1_2_4_to_8(readPtr);
+    }
+
+    if (png_get_valid(readPtr, infoPtr, PNG_INFO_tRNS)) {
+        png_set_tRNS_to_alpha(readPtr);
+    }
+
+    if (bitDepth == 16) {
+        png_set_strip_16(readPtr);
+    }
+
+    if (!(colorType & PNG_COLOR_MASK_ALPHA)) {
+        png_set_add_alpha(readPtr, 0xFF, PNG_FILLER_AFTER);
+    }
+
+    if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+        png_set_gray_to_rgb(readPtr);
+    }
+
+    if (interlaceMethod != PNG_INTERLACE_NONE) {
+        png_set_interlace_handling(readPtr);
+    }
+
+    // Once all the options for reading have been set, we need to flush
+    // them to libpng.
+    png_read_update_info(readPtr, infoPtr);
+
+    // 9-patch uses int32_t to index images, so we cap the image dimensions to something
+    // that can always be represented by 9-patch.
+    if (width > std::numeric_limits<int32_t>::max() ||
+            height > std::numeric_limits<int32_t>::max()) {
+        context->getDiagnostics()->error(DiagMessage() << "PNG image dimensions are too large: "
+                                         << width << "x" << height);
+        return {};
+    }
+
+    std::unique_ptr<Image> outputImage = util::make_unique<Image>();
+    outputImage->width = static_cast<int32_t>(width);
+    outputImage->height = static_cast<int32_t>(height);
+
+    const size_t rowBytes = png_get_rowbytes(readPtr, infoPtr);
+    assert(rowBytes == 4 * width); // RGBA
+
+    // Allocate one large block to hold the image.
+    outputImage->data = std::unique_ptr<uint8_t[]>(new uint8_t[height * rowBytes]);
+
+    // Create an array of rows that index into the data block.
+    outputImage->rows = std::unique_ptr<uint8_t*[]>(new uint8_t*[height]);
+    for (uint32_t h = 0; h < height; h++) {
+        outputImage->rows[h] = outputImage->data.get() + (h * rowBytes);
+    }
+
+    // Actually read the image pixels.
+    png_read_image(readPtr, outputImage->rows.get());
+
+    // Finish reading. This will read any other chunks after the image data.
+    png_read_end(readPtr, infoPtr);
+
+    return outputImage;
+}
+
+/**
+ * Experimentally chosen constant to be added to the overhead of using color type
+ * PNG_COLOR_TYPE_PALETTE to account for the uncompressability of the palette chunk.
+ * Without this, many small PNGs encoded with palettes are larger after compression than
+ * the same PNGs encoded as RGBA.
+ */
+constexpr static const size_t kPaletteOverheadConstant = 1024u * 10u;
+
+// Pick a color type by which to encode the image, based on which color type will take
+// the least amount of disk space.
+//
+// 9-patch images traditionally have not been encoded with palettes.
+// The original rationale was to avoid dithering until after scaling,
+// but I don't think this would be an issue with palettes. Either way,
+// our naive size estimation tends to be wrong for small images like 9-patches
+// and using palettes balloons the size of the resulting 9-patch.
+// In order to not regress in size, restrict 9-patch to not use palettes.
+
+// The options are:
+//
+// - RGB
+// - RGBA
+// - RGB + cheap alpha
+// - Color palette
+// - Color palette + cheap alpha
+// - Color palette + alpha palette
+// - Grayscale
+// - Grayscale + cheap alpha
+// - Grayscale + alpha
+//
+static int pickColorType(int32_t width, int32_t height,
+                         bool grayScale, bool convertibleToGrayScale, bool hasNinePatch,
+                         size_t colorPaletteSize, size_t alphaPaletteSize) {
+    const size_t paletteChunkSize = 16 + colorPaletteSize * 3;
+    const size_t alphaChunkSize = 16 + alphaPaletteSize;
+    const size_t colorAlphaDataChunkSize = 16 + 4 * width * height;
+    const size_t colorDataChunkSize = 16 + 3 * width * height;
+    const size_t grayScaleAlphaDataChunkSize = 16 + 2 * width * height;
+    const size_t paletteDataChunkSize = 16 + width * height;
+
+    if (grayScale) {
+        if (alphaPaletteSize == 0) {
+            // This is the smallest the data can be.
+            return PNG_COLOR_TYPE_GRAY;
+        } else if (colorPaletteSize <= 256 && !hasNinePatch) {
+            // This grayscale has alpha and can fit within a palette.
+            // See if it is worth fitting into a palette.
+            const size_t paletteThreshold = paletteChunkSize + alphaChunkSize +
+                    paletteDataChunkSize + kPaletteOverheadConstant;
+            if (grayScaleAlphaDataChunkSize > paletteThreshold) {
+                return PNG_COLOR_TYPE_PALETTE;
+            }
+        }
+        return PNG_COLOR_TYPE_GRAY_ALPHA;
+    }
+
+
+    if (colorPaletteSize <= 256 && !hasNinePatch) {
+        // This image can fit inside a palette. Let's see if it is worth it.
+        size_t totalSizeWithPalette = paletteDataChunkSize + paletteChunkSize;
+        size_t totalSizeWithoutPalette = colorDataChunkSize;
+        if (alphaPaletteSize > 0) {
+            totalSizeWithPalette += alphaPaletteSize;
+            totalSizeWithoutPalette = colorAlphaDataChunkSize;
+        }
+
+        if (totalSizeWithoutPalette > totalSizeWithPalette + kPaletteOverheadConstant) {
+            return PNG_COLOR_TYPE_PALETTE;
+        }
+    }
+
+    if (convertibleToGrayScale) {
+        if (alphaPaletteSize == 0) {
+            return PNG_COLOR_TYPE_GRAY;
+        } else {
+            return PNG_COLOR_TYPE_GRAY_ALPHA;
+        }
+    }
+
+    if (alphaPaletteSize == 0) {
+        return PNG_COLOR_TYPE_RGB;
+    }
+    return PNG_COLOR_TYPE_RGBA;
+}
+
+// Assigns indices to the color and alpha palettes, encodes them, and then invokes
+// png_set_PLTE/png_set_tRNS.
+// This must be done before writing image data.
+// Image data must be transformed to use the indices assigned within the palette.
+static void writePalette(png_structp writePtr, png_infop writeInfoPtr,
+                  std::unordered_map<uint32_t, int>* colorPalette,
+                  std::unordered_set<uint32_t>* alphaPalette) {
+    assert(colorPalette->size() <= 256);
+    assert(alphaPalette->size() <= 256);
+
+    // Populate the PNG palette struct and assign indices to the color
+    // palette.
+
+    // Colors in the alpha palette should have smaller indices.
+    // This will ensure that we can truncate the alpha palette if it is
+    // smaller than the color palette.
+    int index = 0;
+    for (uint32_t color : *alphaPalette) {
+        (*colorPalette)[color] = index++;
+    }
+
+    // Assign the rest of the entries.
+    for (auto& entry : *colorPalette) {
+        if (entry.second == -1) {
+            entry.second = index++;
+        }
+    }
+
+    // Create the PNG color palette struct.
+    auto colorPaletteBytes = std::unique_ptr<png_color[]>(new png_color[colorPalette->size()]);
+
+    std::unique_ptr<png_byte[]> alphaPaletteBytes;
+    if (!alphaPalette->empty()) {
+        alphaPaletteBytes = std::unique_ptr<png_byte[]>(new png_byte[alphaPalette->size()]);
+    }
+
+    for (const auto& entry : *colorPalette) {
+        const uint32_t color = entry.first;
+        const int index = entry.second;
+        assert(index >= 0);
+        assert(static_cast<size_t>(index) < colorPalette->size());
+
+        png_colorp slot = colorPaletteBytes.get() + index;
+        slot->red = color >> 24;
+        slot->green = color >> 16;
+        slot->blue = color >> 8;
+
+        const png_byte alpha = color & 0x000000ff;
+        if (alpha != 0xff && alphaPaletteBytes) {
+            assert(static_cast<size_t>(index) < alphaPalette->size());
+            alphaPaletteBytes[index] = alpha;
+        }
+    }
+
+    // The bytes get copied here, so it is safe to release colorPaletteBytes at the end of function
+    // scope.
+    png_set_PLTE(writePtr, writeInfoPtr, colorPaletteBytes.get(), colorPalette->size());
+
+    if (alphaPaletteBytes) {
+        png_set_tRNS(writePtr, writeInfoPtr, alphaPaletteBytes.get(), alphaPalette->size(),
+                     nullptr);
+    }
+}
+
+// Write the 9-patch custom PNG chunks to writeInfoPtr. This must be done before
+// writing image data.
+static void writeNinePatch(png_structp writePtr, png_infop writeInfoPtr,
+                           const NinePatch* ninePatch) {
+    // The order of the chunks is important.
+    // 9-patch code in older platforms expects the 9-patch chunk to
+    // be last.
+
+    png_unknown_chunk unknownChunks[3];
+    memset(unknownChunks, 0, sizeof(unknownChunks));
+
+    size_t index = 0;
+    size_t chunkLen = 0;
+
+    std::unique_ptr<uint8_t[]> serializedOutline =
+            ninePatch->serializeRoundedRectOutline(&chunkLen);
+    strcpy((char*) unknownChunks[index].name, "npOl");
+    unknownChunks[index].size = chunkLen;
+    unknownChunks[index].data = (png_bytep) serializedOutline.get();
+    unknownChunks[index].location = PNG_HAVE_PLTE;
+    index++;
+
+    std::unique_ptr<uint8_t[]> serializedLayoutBounds;
+    if (ninePatch->layoutBounds.nonZero()) {
+        serializedLayoutBounds = ninePatch->serializeLayoutBounds(&chunkLen);
+        strcpy((char*) unknownChunks[index].name, "npLb");
+        unknownChunks[index].size = chunkLen;
+        unknownChunks[index].data = (png_bytep) serializedLayoutBounds.get();
+        unknownChunks[index].location = PNG_HAVE_PLTE;
+        index++;
+    }
+
+    std::unique_ptr<uint8_t[]> serializedNinePatch = ninePatch->serializeBase(&chunkLen);
+    strcpy((char*) unknownChunks[index].name, "npTc");
+    unknownChunks[index].size = chunkLen;
+    unknownChunks[index].data = (png_bytep) serializedNinePatch.get();
+    unknownChunks[index].location = PNG_HAVE_PLTE;
+    index++;
+
+    // Handle all unknown chunks. We are manually setting the chunks here,
+    // so we will only ever handle our custom chunks.
+    png_set_keep_unknown_chunks(writePtr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0);
+
+    // Set the actual chunks here. The data gets copied, so our buffers can
+    // safely go out of scope.
+    png_set_unknown_chunks(writePtr, writeInfoPtr, unknownChunks, index);
+}
+
+bool writePng(IAaptContext* context, const Image* image, const NinePatch* ninePatch,
+              io::OutputStream* out, const PngOptions& options) {
+    // Create and initialize the write png_struct with the default error and warning handlers.
+    // The header version is also passed in to ensure that this was built against the same
+    // version of libpng.
+    png_structp writePtr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+                                                   nullptr, nullptr, nullptr);
+    if (writePtr == nullptr) {
+        context->getDiagnostics()->error(DiagMessage()
+                                         << "failed to create libpng write png_struct");
+        return false;
+    }
+
+    // Allocate memory to store image header data.
+    png_infop writeInfoPtr = png_create_info_struct(writePtr);
+    if (writeInfoPtr == nullptr) {
+        context->getDiagnostics()->error(DiagMessage() << "failed to create libpng write png_info");
+        png_destroy_write_struct(&writePtr, nullptr);
+        return false;
+    }
+
+    // Automatically release PNG resources at end of scope.
+    PngWriteStructDeleter pngWriteDeleter(writePtr, writeInfoPtr);
+
+    // libpng uses longjmp to jump to error handling routines.
+    // setjmp will return true only if it was jumped to, aka, there was an error.
+    if (setjmp(png_jmpbuf(writePtr))) {
+        return false;
+    }
+
+    // Handle warnings with our IDiagnostics.
+    png_set_error_fn(writePtr, (png_voidp) context->getDiagnostics(), logError, logWarning);
+
+    // Set up the write functions which write to our custom data sources.
+    png_set_write_fn(writePtr, (png_voidp) out, writeDataToStream, nullptr);
+
+    // We want small files and can take the performance hit to achieve this goal.
+    png_set_compression_level(writePtr, Z_BEST_COMPRESSION);
+
+    // Begin analysis of the image data.
+    // Scan the entire image and determine if:
+    // 1. Every pixel has R == G == B (grayscale)
+    // 2. Every pixel has A == 255 (opaque)
+    // 3. There are no more than 256 distinct RGBA colors (palette).
+    std::unordered_map<uint32_t, int> colorPalette;
+    std::unordered_set<uint32_t> alphaPalette;
+    bool needsToZeroRGBChannelsOfTransparentPixels = false;
+    bool grayScale = true;
+    int maxGrayDeviation = 0;
+
+    for (int32_t y = 0; y < image->height; y++) {
+        const uint8_t* row = image->rows[y];
+        for (int32_t x = 0; x < image->width; x++) {
+            int red = *row++;
+            int green = *row++;
+            int blue = *row++;
+            int alpha = *row++;
+
+            if (alpha == 0) {
+                // The color is completely transparent.
+                // For purposes of palettes and grayscale optimization,
+                // treat all channels as 0x00.
+                needsToZeroRGBChannelsOfTransparentPixels =
+                        needsToZeroRGBChannelsOfTransparentPixels ||
+                        (red != 0 || green != 0 || blue != 0);
+                red = green = blue = 0;
+            }
+
+            // Insert the color into the color palette.
+            const uint32_t color = red << 24 | green << 16 | blue << 8 | alpha;
+            colorPalette[color] = -1;
+
+            // If the pixel has non-opaque alpha, insert it into the
+            // alpha palette.
+            if (alpha != 0xff) {
+                alphaPalette.insert(color);
+            }
+
+            // Check if the image is indeed grayscale.
+            if (grayScale) {
+                if (red != green || red != blue) {
+                    grayScale = false;
+                }
+            }
+
+            // Calculate the gray scale deviation so that it can be compared
+            // with the threshold.
+            maxGrayDeviation = std::max(std::abs(red - green), maxGrayDeviation);
+            maxGrayDeviation = std::max(std::abs(green - blue), maxGrayDeviation);
+            maxGrayDeviation = std::max(std::abs(blue - red), maxGrayDeviation);
+        }
+    }
+
+    if (context->verbose()) {
+        DiagMessage msg;
+        msg << " paletteSize=" << colorPalette.size()
+                << " alphaPaletteSize=" << alphaPalette.size()
+                << " maxGrayDeviation=" << maxGrayDeviation
+                << " grayScale=" << (grayScale ? "true" : "false");
+        context->getDiagnostics()->note(msg);
+    }
+
+    const bool convertibleToGrayScale = maxGrayDeviation <= options.grayScaleTolerance;
+
+    const int newColorType = pickColorType(image->width, image->height, grayScale,
+                                           convertibleToGrayScale, ninePatch != nullptr,
+                                           colorPalette.size(), alphaPalette.size());
+
+    if (context->verbose()) {
+        DiagMessage msg;
+        msg << "encoding PNG ";
+        if (ninePatch) {
+            msg << "(with 9-patch) as ";
+        }
+        switch (newColorType) {
+        case PNG_COLOR_TYPE_GRAY:
+            msg << "GRAY";
+            break;
+        case PNG_COLOR_TYPE_GRAY_ALPHA:
+            msg << "GRAY + ALPHA";
+            break;
+        case PNG_COLOR_TYPE_RGB:
+            msg << "RGB";
+            break;
+        case PNG_COLOR_TYPE_RGB_ALPHA:
+            msg << "RGBA";
+            break;
+        case PNG_COLOR_TYPE_PALETTE:
+            msg << "PALETTE";
+            break;
+        default:
+            msg << "unknown type " << newColorType;
+            break;
+        }
+        context->getDiagnostics()->note(msg);
+    }
+
+    png_set_IHDR(writePtr, writeInfoPtr, image->width, image->height, 8, newColorType,
+                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+    if (newColorType & PNG_COLOR_MASK_PALETTE) {
+        // Assigns indices to the palette, and writes the encoded palette to the libpng writePtr.
+        writePalette(writePtr, writeInfoPtr, &colorPalette, &alphaPalette);
+        png_set_filter(writePtr, 0, PNG_NO_FILTERS);
+    } else {
+        png_set_filter(writePtr, 0, PNG_ALL_FILTERS);
+    }
+
+    if (ninePatch) {
+        writeNinePatch(writePtr, writeInfoPtr, ninePatch);
+    }
+
+    // Flush our updates to the header.
+    png_write_info(writePtr, writeInfoPtr);
+
+    // Write out each row of image data according to its encoding.
+    if (newColorType == PNG_COLOR_TYPE_PALETTE) {
+        // 1 byte/pixel.
+        auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width]);
+
+        for (int32_t y = 0; y < image->height; y++) {
+            png_const_bytep inRow = image->rows[y];
+            for (int32_t x = 0; x < image->width; x++) {
+                int rr = *inRow++;
+                int gg = *inRow++;
+                int bb = *inRow++;
+                int aa = *inRow++;
+                if (aa == 0) {
+                    // Zero out color channels when transparent.
+                    rr = gg = bb = 0;
+                }
+
+                const uint32_t color = rr << 24 | gg << 16 | bb << 8 | aa;
+                const int idx = colorPalette[color];
+                assert(idx != -1);
+                outRow[x] = static_cast<png_byte>(idx);
+            }
+            png_write_row(writePtr, outRow.get());
+        }
+    } else if (newColorType == PNG_COLOR_TYPE_GRAY || newColorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+        const size_t bpp = newColorType == PNG_COLOR_TYPE_GRAY ? 1 : 2;
+        auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
+
+        for (int32_t y = 0; y < image->height; y++) {
+            png_const_bytep inRow = image->rows[y];
+            for (int32_t x = 0; x < image->width; x++) {
+                int rr = inRow[x * 4];
+                int gg = inRow[x * 4 + 1];
+                int bb = inRow[x * 4 + 2];
+                int aa = inRow[x * 4 + 3];
+                if (aa == 0) {
+                    // Zero out the gray channel when transparent.
+                    rr = gg = bb = 0;
+                }
+
+                if (grayScale) {
+                    // The image was already grayscale, red == green == blue.
+                    outRow[x * bpp] = inRow[x * 4];
+                } else {
+                    // The image is convertible to grayscale, use linear-luminance of
+                    // sRGB colorspace: https://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale
+                    outRow[x * bpp] = (png_byte) (rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
+                }
+
+                if (bpp == 2) {
+                    // Write out alpha if we have it.
+                    outRow[x * bpp + 1] = aa;
+                }
+            }
+            png_write_row(writePtr, outRow.get());
+        }
+    } else if (newColorType == PNG_COLOR_TYPE_RGB || newColorType == PNG_COLOR_TYPE_RGBA) {
+        const size_t bpp = newColorType == PNG_COLOR_TYPE_RGB ? 3 : 4;
+        if (needsToZeroRGBChannelsOfTransparentPixels) {
+            // The source RGBA data can't be used as-is, because we need to zero out the RGB
+            // values of transparent pixels.
+            auto outRow = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
+
+            for (int32_t y = 0; y < image->height; y++) {
+                png_const_bytep inRow = image->rows[y];
+                for (int32_t x = 0; x < image->width; x++) {
+                    int rr = *inRow++;
+                    int gg = *inRow++;
+                    int bb = *inRow++;
+                    int aa = *inRow++;
+                    if (aa == 0) {
+                        // Zero out the RGB channels when transparent.
+                        rr = gg = bb = 0;
+                    }
+                    outRow[x * bpp] = rr;
+                    outRow[x * bpp + 1] = gg;
+                    outRow[x * bpp + 2] = bb;
+                    if (bpp == 4) {
+                        outRow[x * bpp + 3] = aa;
+                    }
+                }
+                png_write_row(writePtr, outRow.get());
+            }
+        } else {
+            // The source image can be used as-is, just tell libpng whether or not to ignore
+            // the alpha channel.
+            if (newColorType == PNG_COLOR_TYPE_RGB) {
+                // Delete the extraneous alpha values that we appended to our buffer
+                // when reading the original values.
+                png_set_filler(writePtr, 0, PNG_FILLER_AFTER);
+            }
+            png_write_image(writePtr, image->rows.get());
+        }
+    } else {
+        assert(false && "unreachable");
+    }
+
+    png_write_end(writePtr, writeInfoPtr);
+    return true;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/cheap_transparency.png b/tools/aapt2/integration-tests/AppOne/res/drawable/cheap_transparency.png
new file mode 100644
index 0000000..0522a99
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/cheap_transparency.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/complex.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/complex.9.png
new file mode 100644
index 0000000..baf9fff
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/complex.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/outline_8x8.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/outline_8x8.9.png
new file mode 100644
index 0000000..7b331e1
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/outline_8x8.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_off_center_outline_32x16.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_off_center_outline_32x16.9.png
new file mode 100644
index 0000000..0ec6c70
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_off_center_outline_32x16.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_outline_32x16.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_outline_32x16.9.png
new file mode 100644
index 0000000..e05708a
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/round_rect_outline_32x16.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_3x3.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_3x3.9.png
new file mode 100644
index 0000000..a11377a
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_3x3.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_optical_bounds_3x3.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_optical_bounds_3x3.9.png
new file mode 100644
index 0000000..6803e42
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/transparent_optical_bounds_3x3.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/white_3x3.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/white_3x3.9.png
new file mode 100644
index 0000000..1a3731b
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/white_3x3.9.png
Binary files differ
diff --git a/tools/aapt2/integration-tests/AppOne/res/drawable/white_optical_bounds_3x3.9.png b/tools/aapt2/integration-tests/AppOne/res/drawable/white_optical_bounds_3x3.9.png
new file mode 100644
index 0000000..489ace2
--- /dev/null
+++ b/tools/aapt2/integration-tests/AppOne/res/drawable/white_optical_bounds_3x3.9.png
Binary files differ
diff --git a/tools/aapt2/io/Io.cpp b/tools/aapt2/io/Io.cpp
new file mode 100644
index 0000000..963c21c
--- /dev/null
+++ b/tools/aapt2/io/Io.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "io/Io.h"
+
+#include <algorithm>
+#include <cstring>
+
+namespace aapt {
+namespace io {
+
+bool copy(OutputStream* out, InputStream* in) {
+    const void* inBuffer;
+    int inLen;
+    while (in->Next(&inBuffer, &inLen)) {
+        void* outBuffer;
+        int outLen;
+        if (!out->Next(&outBuffer, &outLen)) {
+            return !out->HadError();
+        }
+
+        const int bytesToCopy = std::min(inLen, outLen);
+        memcpy(outBuffer, inBuffer, bytesToCopy);
+        out->BackUp(outLen - bytesToCopy);
+        in->BackUp(inLen - bytesToCopy);
+    }
+    return !in->HadError();
+}
+
+} // namespace io
+} // namespace aapt
diff --git a/tools/aapt2/io/Io.h b/tools/aapt2/io/Io.h
new file mode 100644
index 0000000..e1e9107
--- /dev/null
+++ b/tools/aapt2/io/Io.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_IO_IO_H
+#define AAPT_IO_IO_H
+
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <string>
+
+namespace aapt {
+namespace io {
+
+/**
+ * InputStream interface that inherits from protobuf's ZeroCopyInputStream,
+ * but adds error handling methods to better report issues.
+ *
+ * The code style here matches the protobuf style.
+ */
+class InputStream : public google::protobuf::io::ZeroCopyInputStream {
+public:
+    virtual std::string GetError() const {
+        return {};
+    }
+
+    virtual bool HadError() const = 0;
+};
+
+/**
+ * OutputStream interface that inherits from protobuf's ZeroCopyOutputStream,
+ * but adds error handling methods to better report issues.
+ *
+ * The code style here matches the protobuf style.
+ */
+class OutputStream : public google::protobuf::io::ZeroCopyOutputStream {
+public:
+    virtual std::string GetError() const {
+        return {};
+    }
+
+    virtual bool HadError() const = 0;
+};
+
+/**
+ * Copies the data from in to out. Returns true if there was no error.
+ * If there was an error, check the individual streams' HadError/GetError
+ * methods.
+ */
+bool copy(OutputStream* out, InputStream* in);
+
+} // namespace io
+} // namespace aapt
+
+#endif /* AAPT_IO_IO_H */
diff --git a/tools/aapt2/util/BigBuffer.cpp b/tools/aapt2/util/BigBuffer.cpp
index c88e3c1..de4ecd2 100644
--- a/tools/aapt2/util/BigBuffer.cpp
+++ b/tools/aapt2/util/BigBuffer.cpp
@@ -49,4 +49,29 @@
     return mBlocks.back().buffer.get();
 }
 
+void* BigBuffer::nextBlock(size_t* outSize) {
+    if (!mBlocks.empty()) {
+        Block& block = mBlocks.back();
+        if (block.size != block.mBlockSize) {
+            void* outBuffer = block.buffer.get() + block.size;
+            size_t size = block.mBlockSize - block.size;
+            block.size = block.mBlockSize;
+            mSize += size;
+            *outSize = size;
+            return outBuffer;
+        }
+    }
+
+    // Zero-allocate the block's buffer.
+    Block block = {};
+    block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[mBlockSize]());
+    assert(block.buffer);
+    block.size = mBlockSize;
+    block.mBlockSize = mBlockSize;
+    mBlocks.push_back(std::move(block));
+    mSize += mBlockSize;
+    *outSize = mBlockSize;
+    return mBlocks.back().buffer.get();
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/util/BigBuffer.h b/tools/aapt2/util/BigBuffer.h
index ba8532f..685614f 100644
--- a/tools/aapt2/util/BigBuffer.h
+++ b/tools/aapt2/util/BigBuffer.h
@@ -82,6 +82,20 @@
     T* nextBlock(size_t count = 1);
 
     /**
+     * Returns the next block available and puts the size in outCount.
+     * This is useful for grabbing blocks where the size doesn't matter.
+     * Use backUp() to give back any bytes that were not used.
+     */
+    void* nextBlock(size_t* outCount);
+
+    /**
+     * Backs up count bytes. This must only be called after nextBlock()
+     * and can not be larger than sizeof(T) * count of the last nextBlock()
+     * call.
+     */
+    void backUp(size_t count);
+
+    /**
      * Moves the specified BigBuffer into this one. When this method
      * returns, buffer is empty.
      */
@@ -97,6 +111,8 @@
      */
     void align4();
 
+    size_t getBlockSize() const;
+
     const_iterator begin() const;
     const_iterator end() const;
 
@@ -123,6 +139,10 @@
     return mSize;
 }
 
+inline size_t BigBuffer::getBlockSize() const {
+    return mBlockSize;
+}
+
 template <typename T>
 inline T* BigBuffer::nextBlock(size_t count) {
     static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type");
@@ -130,6 +150,12 @@
     return reinterpret_cast<T*>(nextBlockImpl(sizeof(T) * count));
 }
 
+inline void BigBuffer::backUp(size_t count) {
+    Block& block = mBlocks.back();
+    block.size -= count;
+    mSize -= count;
+}
+
 inline void BigBuffer::appendBuffer(BigBuffer&& buffer) {
     std::move(buffer.mBlocks.begin(), buffer.mBlocks.end(), std::back_inserter(mBlocks));
     mSize += buffer.mSize;
diff --git a/tools/aapt2/util/StringPiece.h b/tools/aapt2/util/StringPiece.h
index 4300a67..266c003 100644
--- a/tools/aapt2/util/StringPiece.h
+++ b/tools/aapt2/util/StringPiece.h
@@ -39,6 +39,9 @@
     using const_iterator = const TChar*;
     using difference_type = size_t;
 
+    // End of string marker.
+    constexpr static const size_t npos = static_cast<size_t>(-1);
+
     BasicStringPiece();
     BasicStringPiece(const BasicStringPiece<TChar>& str);
     BasicStringPiece(const std::basic_string<TChar>& str);  // NOLINT(implicit)
@@ -48,7 +51,7 @@
     BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs);
     BasicStringPiece<TChar>& assign(const TChar* str, size_t len);
 
-    BasicStringPiece<TChar> substr(size_t start, size_t len) const;
+    BasicStringPiece<TChar> substr(size_t start, size_t len = npos) const;
     BasicStringPiece<TChar> substr(BasicStringPiece<TChar>::const_iterator begin,
                                    BasicStringPiece<TChar>::const_iterator end) const;
 
@@ -81,6 +84,9 @@
 //
 
 template <typename TChar>
+constexpr const size_t BasicStringPiece<TChar>::npos;
+
+template <typename TChar>
 inline BasicStringPiece<TChar>::BasicStringPiece() : mData(nullptr) , mLength(0) {
 }
 
@@ -127,7 +133,11 @@
 
 template <typename TChar>
 inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const {
-    if (start + len > mLength) {
+    if (len == npos) {
+        len = mLength - start;
+    }
+
+    if (start > mLength || start + len > mLength) {
         return BasicStringPiece<TChar>();
     }
     return BasicStringPiece<TChar>(mData + start, len);
