diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 47a7f35..2f28363 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -63,15 +63,21 @@
         "AssetsProvider.cpp",
         "AttributeResolution.cpp",
         "BigBuffer.cpp",
+        "BigBufferStream.cpp",
         "ChunkIterator.cpp",
         "ConfigDescription.cpp",
+        "FileStream.cpp",
         "Idmap.cpp",
         "LoadedArsc.cpp",
         "Locale.cpp",
         "LocaleData.cpp",
         "misc.cpp",
+        "NinePatch.cpp",
         "ObbFile.cpp",
         "PosixUtils.cpp",
+        "Png.cpp",
+        "PngChunkFilter.cpp",
+        "PngCrunch.cpp",
         "ResourceTimer.cpp",
         "ResourceTypes.cpp",
         "ResourceUtils.cpp",
@@ -84,7 +90,10 @@
     ],
     export_include_dirs: ["include"],
     export_shared_lib_headers: ["libz"],
-    static_libs: ["libincfs-utils"],
+    static_libs: [
+        "libincfs-utils",
+        "libpng",
+    ],
     whole_static_libs: [
         "libandroidfw_pathutils",
         "libincfs-utils",
@@ -198,9 +207,11 @@
         "tests/ConfigDescription_test.cpp",
         "tests/ConfigLocale_test.cpp",
         "tests/DynamicRefTable_test.cpp",
+        "tests/FileStream_test.cpp",
         "tests/Idmap_test.cpp",
         "tests/LoadedArsc_test.cpp",
         "tests/Locale_test.cpp",
+        "tests/NinePatch_test.cpp",
         "tests/ResourceTimer_test.cpp",
         "tests/ResourceUtils_test.cpp",
         "tests/ResTable_test.cpp",
diff --git a/libs/androidfw/BigBufferStream.cpp b/libs/androidfw/BigBufferStream.cpp
new file mode 100644
index 0000000..f18199c
--- /dev/null
+++ b/libs/androidfw/BigBufferStream.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2017 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 "androidfw/BigBufferStream.h"
+
+#include <algorithm>
+
+namespace android {
+
+//
+// BigBufferInputStream
+//
+
+bool BigBufferInputStream::Next(const void** data, size_t* size) {
+  if (iter_ == buffer_->end()) {
+    return false;
+  }
+
+  if (offset_ == iter_->size) {
+    ++iter_;
+    if (iter_ == buffer_->end()) {
+      return false;
+    }
+    offset_ = 0;
+  }
+
+  *data = iter_->buffer.get() + offset_;
+  *size = iter_->size - offset_;
+  bytes_read_ += iter_->size - offset_;
+  offset_ = iter_->size;
+  return true;
+}
+
+void BigBufferInputStream::BackUp(size_t count) {
+  if (count > offset_) {
+    bytes_read_ -= offset_;
+    offset_ = 0;
+  } else {
+    offset_ -= count;
+    bytes_read_ -= count;
+  }
+}
+
+bool BigBufferInputStream::CanRewind() const {
+  return true;
+}
+
+bool BigBufferInputStream::Rewind() {
+  iter_ = buffer_->begin();
+  offset_ = 0;
+  bytes_read_ = 0;
+  return true;
+}
+
+size_t BigBufferInputStream::ByteCount() const {
+  return bytes_read_;
+}
+
+bool BigBufferInputStream::HadError() const {
+  return false;
+}
+
+size_t BigBufferInputStream::TotalSize() const {
+  return buffer_->size();
+}
+
+bool BigBufferInputStream::ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
+  if (byte_count == 0) {
+    return true;
+  }
+  if (offset < 0) {
+    return false;
+  }
+  if (offset > std::numeric_limits<off64_t>::max() - byte_count) {
+    return false;
+  }
+  if (offset + byte_count > buffer_->size()) {
+    return false;
+  }
+  auto p = reinterpret_cast<uint8_t*>(data);
+  for (auto iter = buffer_->begin(); iter != buffer_->end() && byte_count > 0; ++iter) {
+    if (offset < iter->size) {
+      size_t to_read = std::min(byte_count, (size_t)(iter->size - offset));
+      memcpy(p, iter->buffer.get() + offset, to_read);
+      byte_count -= to_read;
+      p += to_read;
+      offset = 0;
+    } else {
+      offset -= iter->size;
+    }
+  }
+  return byte_count == 0;
+}
+
+//
+// BigBufferOutputStream
+//
+
+bool BigBufferOutputStream::Next(void** data, size_t* size) {
+  *data = buffer_->NextBlock(size);
+  return true;
+}
+
+void BigBufferOutputStream::BackUp(size_t count) {
+  buffer_->BackUp(count);
+}
+
+size_t BigBufferOutputStream::ByteCount() const {
+  return buffer_->size();
+}
+
+bool BigBufferOutputStream::HadError() const {
+  return false;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/FileStream.cpp b/libs/androidfw/FileStream.cpp
new file mode 100644
index 0000000..b86c9cb
--- /dev/null
+++ b/libs/androidfw/FileStream.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2017 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 "androidfw/FileStream.h"
+
+#include <errno.h>   // for errno
+#include <fcntl.h>   // for O_RDONLY
+#include <unistd.h>  // for read
+
+#include "android-base/errors.h"
+#include "android-base/file.h"  // for O_BINARY
+#include "android-base/macros.h"
+#include "android-base/utf8.h"
+
+#if defined(_WIN32)
+// This is only needed for O_CLOEXEC.
+#include <windows.h>
+#define O_CLOEXEC O_NOINHERIT
+#endif
+
+using ::android::base::SystemErrorCodeToString;
+using ::android::base::unique_fd;
+
+namespace android {
+
+FileInputStream::FileInputStream(const std::string& path, size_t buffer_capacity)
+    : buffer_capacity_(buffer_capacity) {
+  int mode = O_RDONLY | O_CLOEXEC | O_BINARY;
+  fd_.reset(TEMP_FAILURE_RETRY(::android::base::utf8::open(path.c_str(), mode)));
+  if (fd_ == -1) {
+    error_ = SystemErrorCodeToString(errno);
+  } else {
+    buffer_.reset(new uint8_t[buffer_capacity_]);
+  }
+}
+
+FileInputStream::FileInputStream(int fd, size_t buffer_capacity)
+    : fd_(fd), buffer_capacity_(buffer_capacity) {
+  if (fd_ < 0) {
+    error_ = "Bad File Descriptor";
+  } else {
+    buffer_.reset(new uint8_t[buffer_capacity_]);
+  }
+}
+
+bool FileInputStream::Next(const void** data, size_t* size) {
+  if (HadError()) {
+    return false;
+  }
+
+  // Deal with any remaining bytes after BackUp was called.
+  if (buffer_offset_ != buffer_size_) {
+    *data = buffer_.get() + buffer_offset_;
+    *size = buffer_size_ - buffer_offset_;
+    total_byte_count_ += buffer_size_ - buffer_offset_;
+    buffer_offset_ = buffer_size_;
+    return true;
+  }
+
+  ssize_t n = TEMP_FAILURE_RETRY(read(fd_, buffer_.get(), buffer_capacity_));
+  if (n < 0) {
+    error_ = SystemErrorCodeToString(errno);
+    fd_.reset();
+    buffer_.reset();
+    return false;
+  }
+
+  buffer_size_ = static_cast<size_t>(n);
+  buffer_offset_ = buffer_size_;
+  total_byte_count_ += buffer_size_;
+
+  *data = buffer_.get();
+  *size = buffer_size_;
+  return buffer_size_ != 0u;
+}
+
+void FileInputStream::BackUp(size_t count) {
+  if (count > buffer_offset_) {
+    count = buffer_offset_;
+  }
+  buffer_offset_ -= count;
+  total_byte_count_ -= count;
+}
+
+size_t FileInputStream::ByteCount() const {
+  return total_byte_count_;
+}
+
+bool FileInputStream::HadError() const {
+  return fd_ == -1;
+}
+
+std::string FileInputStream::GetError() const {
+  return error_;
+}
+
+bool FileInputStream::ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
+  return base::ReadFullyAtOffset(fd_, data, byte_count, offset);
+}
+
+FileOutputStream::FileOutputStream(const std::string& path, size_t buffer_capacity)
+    : buffer_capacity_(buffer_capacity) {
+  int mode = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY;
+  owned_fd_.reset(TEMP_FAILURE_RETRY(::android::base::utf8::open(path.c_str(), mode, 0666)));
+  fd_ = owned_fd_.get();
+  if (fd_ < 0) {
+    error_ = SystemErrorCodeToString(errno);
+  } else {
+    buffer_.reset(new uint8_t[buffer_capacity_]);
+  }
+}
+
+FileOutputStream::FileOutputStream(unique_fd fd, size_t buffer_capacity)
+    : FileOutputStream(fd.get(), buffer_capacity) {
+  owned_fd_ = std::move(fd);
+}
+
+FileOutputStream::FileOutputStream(int fd, size_t buffer_capacity)
+    : fd_(fd), buffer_capacity_(buffer_capacity) {
+  if (fd_ < 0) {
+    error_ = "Bad File Descriptor";
+  } else {
+    buffer_.reset(new uint8_t[buffer_capacity_]);
+  }
+}
+
+FileOutputStream::~FileOutputStream() {
+  // Flush the buffer.
+  Flush();
+}
+
+bool FileOutputStream::Next(void** data, size_t* size) {
+  if (HadError()) {
+    return false;
+  }
+
+  if (buffer_offset_ == buffer_capacity_) {
+    if (!FlushImpl()) {
+      return false;
+    }
+  }
+
+  const size_t buffer_size = buffer_capacity_ - buffer_offset_;
+  *data = buffer_.get() + buffer_offset_;
+  *size = buffer_size;
+  total_byte_count_ += buffer_size;
+  buffer_offset_ = buffer_capacity_;
+  return true;
+}
+
+void FileOutputStream::BackUp(size_t count) {
+  if (count > buffer_offset_) {
+    count = buffer_offset_;
+  }
+  buffer_offset_ -= count;
+  total_byte_count_ -= count;
+}
+
+size_t FileOutputStream::ByteCount() const {
+  return total_byte_count_;
+}
+
+bool FileOutputStream::Flush() {
+  if (!HadError()) {
+    return FlushImpl();
+  }
+  return false;
+}
+
+bool FileOutputStream::FlushImpl() {
+  ssize_t n = TEMP_FAILURE_RETRY(write(fd_, buffer_.get(), buffer_offset_));
+  if (n < 0) {
+    error_ = SystemErrorCodeToString(errno);
+    owned_fd_.reset();
+    fd_ = -1;
+    buffer_.reset();
+    return false;
+  }
+
+  buffer_offset_ = 0u;
+  return true;
+}
+
+bool FileOutputStream::HadError() const {
+  return fd_ == -1;
+}
+
+std::string FileOutputStream::GetError() const {
+  return error_;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/NinePatch.cpp b/libs/androidfw/NinePatch.cpp
new file mode 100644
index 0000000..1fdbebf
--- /dev/null
+++ b/libs/androidfw/NinePatch.cpp
@@ -0,0 +1,682 @@
+/*
+ * 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 <sstream>
+#include <string>
+#include <vector>
+
+#include "androidfw/Image.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+
+using android::StringPiece;
+
+namespace android {
+
+// 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 get_alpha(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* image_line, const ColorValidator* color_validator,
+                       std::vector<Range>* primary_ranges, std::vector<Range>* secondary_ranges,
+                       std::string* out_err) {
+  const int32_t length = image_line->GetLength();
+
+  uint32_t last_color = 0xffffffffu;
+  for (int32_t idx = 1; idx < length - 1; idx++) {
+    const uint32_t color = image_line->GetColor(idx);
+    if (!color_validator->IsValidColor(color)) {
+      *out_err = "found an invalid color";
+      return false;
+    }
+
+    if (color != last_color) {
+      // We are ending a range. Which range?
+      // note: encode the x offset without the final 1 pixel border.
+      if (last_color == kPrimaryColor) {
+        primary_ranges->back().end = idx - 1;
+      } else if (last_color == kSecondaryColor) {
+        secondary_ranges->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) {
+        primary_ranges->push_back(Range(idx - 1, length - 2));
+      } else if (color == kSecondaryColor) {
+        secondary_ranges->push_back(Range(idx - 1, length - 2));
+      }
+      last_color = 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)
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_] + (idx + xoffset_) * 4);
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
+
+  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)
+      : rows_(rows), xoffset_(xoffset), yoffset_(yoffset), length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + idx] + (xoffset_ * 4));
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, length_;
+
+  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)
+      : rows_(rows),
+        xoffset_(xoffset),
+        yoffset_(yoffset),
+        xstep_(xstep),
+        ystep_(ystep),
+        length_(length) {
+  }
+
+  inline int32_t GetLength() const {
+    return length_;
+  }
+
+  inline uint32_t GetColor(int32_t idx) const {
+    return NinePatch::PackRGBA(rows_[yoffset_ + (idx * ystep_)] + ((idx + xoffset_) * xstep_) * 4);
+  }
+
+ private:
+  uint8_t** rows_;
+  int32_t xoffset_, yoffset_, xstep_, ystep_, length_;
+
+  DISALLOW_COPY_AND_ASSIGN(DiagonalImageLine);
+};
+
+class TransparentNeutralColorValidator : public ColorValidator {
+ public:
+  bool IsNeutralColor(uint32_t color) const override {
+    return get_alpha(color) == 0;
+  }
+};
+
+class WhiteNeutralColorValidator : public ColorValidator {
+ public:
+  bool IsNeutralColor(uint32_t color) const override {
+    return color == kColorOpaqueWhite;
+  }
+};
+
+inline static uint32_t get_alpha(uint32_t color) {
+  return (color & 0xff000000u) >> 24;
+}
+
+static bool PopulateBounds(const std::vector<Range>& padding,
+                           const std::vector<Range>& layout_bounds,
+                           const std::vector<Range>& stretch_regions, const int32_t length,
+                           int32_t* padding_start, int32_t* padding_end, int32_t* layout_start,
+                           int32_t* layout_end, StringPiece edge_name, std::string* out_err) {
+  if (padding.size() > 1) {
+    std::stringstream err_stream;
+    err_stream << "too many padding sections on " << edge_name << " border";
+    *out_err = err_stream.str();
+    return false;
+  }
+
+  *padding_start = 0;
+  *padding_end = 0;
+  if (!padding.empty()) {
+    const Range& range = padding.front();
+    *padding_start = range.start;
+    *padding_end = length - range.end;
+  } else if (!stretch_regions.empty()) {
+    // No padding was defined. Compute the padding from the first and last
+    // stretch regions.
+    *padding_start = stretch_regions.front().start;
+    *padding_end = length - stretch_regions.back().end;
+  }
+
+  if (layout_bounds.size() > 2) {
+    std::stringstream err_stream;
+    err_stream << "too many layout bounds sections on " << edge_name << " border";
+    *out_err = err_stream.str();
+    return false;
+  }
+
+  *layout_start = 0;
+  *layout_end = 0;
+  if (layout_bounds.size() >= 1) {
+    const Range& range = layout_bounds.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 err_stream;
+      err_stream << "layout bounds on " << edge_name << " border must start at edge";
+      *out_err = err_stream.str();
+      return false;
+    }
+    *layout_start = range.end;
+
+    if (layout_bounds.size() >= 2) {
+      const Range& range = layout_bounds.back();
+      if (range.end != length) {
+        std::stringstream err_stream;
+        err_stream << "layout bounds on " << edge_name << " border must start at edge";
+        *out_err = err_stream.str();
+        return false;
+      }
+      *layout_end = length - range.start;
+    }
+  }
+  return true;
+}
+
+static int32_t CalculateSegmentCount(const std::vector<Range>& stretch_regions, int32_t length) {
+  if (stretch_regions.size() == 0) {
+    return 0;
+  }
+
+  const bool start_is_fixed = stretch_regions.front().start != 0;
+  const bool end_is_fixed = stretch_regions.back().end != length;
+  int32_t modifier = 0;
+  if (start_is_fixed && end_is_fixed) {
+    modifier = 1;
+  } else if (!start_is_fixed && !end_is_fixed) {
+    modifier = -1;
+  }
+  return static_cast<int32_t>(stretch_regions.size()) * 2 + modifier;
+}
+
+static uint32_t GetRegionColor(uint8_t** rows, const Bounds& region) {
+  // Sample the first pixel to compare against.
+  const uint32_t expected_color = 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 (get_alpha(color) == 0) {
+        // The color is transparent.
+        // If the expectedColor is not transparent, NO_COLOR.
+        if (get_alpha(expected_color) != 0) {
+          return android::Res_png_9patch::NO_COLOR;
+        }
+      } else if (color != expected_color) {
+        return android::Res_png_9patch::NO_COLOR;
+      }
+    }
+  }
+
+  if (get_alpha(expected_color) == 0) {
+    return android::Res_png_9patch::TRANSPARENT_COLOR;
+  }
+  return expected_color;
+}
+
+// Fills out_colors with each 9-patch section's color. If the whole section is
+// transparent,
+// it gets the special TRANSPARENT color. If the whole section is the same
+// color, it is assigned
+// that color. Otherwise it gets the special NO_COLOR color.
+//
+// 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>& horizontal_stretch_regions,
+                                  const std::vector<Range>& vertical_stretch_regions,
+                                  const int32_t width, const int32_t height,
+                                  std::vector<uint32_t>* out_colors) {
+  int32_t next_top = 0;
+  Bounds bounds;
+  auto row_iter = vertical_stretch_regions.begin();
+  while (next_top != height) {
+    if (row_iter != vertical_stretch_regions.end()) {
+      if (next_top != row_iter->start) {
+        // This is a fixed segment.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.top = next_top + 1;
+        bounds.bottom = row_iter->start + 1;
+        next_top = row_iter->start;
+      } else {
+        // This is a stretchy segment.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.top = row_iter->start + 1;
+        bounds.bottom = row_iter->end + 1;
+        next_top = row_iter->end;
+        ++row_iter;
+      }
+    } else {
+      // This is the end, fixed section.
+      // Offset the bounds by 1 to accommodate the border.
+      bounds.top = next_top + 1;
+      bounds.bottom = height + 1;
+      next_top = height;
+    }
+
+    int32_t next_left = 0;
+    auto col_iter = horizontal_stretch_regions.begin();
+    while (next_left != width) {
+      if (col_iter != horizontal_stretch_regions.end()) {
+        if (next_left != col_iter->start) {
+          // This is a fixed segment.
+          // Offset the bounds by 1 to accommodate the border.
+          bounds.left = next_left + 1;
+          bounds.right = col_iter->start + 1;
+          next_left = col_iter->start;
+        } else {
+          // This is a stretchy segment.
+          // Offset the bounds by 1 to accommodate the border.
+          bounds.left = col_iter->start + 1;
+          bounds.right = col_iter->end + 1;
+          next_left = col_iter->end;
+          ++col_iter;
+        }
+      } else {
+        // This is the end, fixed section.
+        // Offset the bounds by 1 to accommodate the border.
+        bounds.left = next_left + 1;
+        bounds.right = width + 1;
+        next_left = width;
+      }
+      out_colors->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* image_line, int32_t* out_start, int32_t* out_end) {
+  *out_start = 0;
+  *out_end = 0;
+
+  const int32_t length = image_line->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 max_alpha = 0;
+  for (int32_t i = 0; i < mid1 && max_alpha != 0xff; i++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_start = i;
+    }
+  }
+
+  max_alpha = 0;
+  for (int32_t i = length - 1; i >= mid2 && max_alpha != 0xff; i--) {
+    uint32_t alpha = get_alpha(image_line->GetColor(i));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+      *out_end = length - (i + 1);
+    }
+  }
+  return;
+}
+
+template <typename ImageLine>
+static uint32_t FindMaxAlpha(const ImageLine* image_line) {
+  const int32_t length = image_line->GetLength();
+  uint32_t max_alpha = 0;
+  for (int32_t idx = 0; idx < length && max_alpha != 0xff; idx++) {
+    uint32_t alpha = get_alpha(image_line->GetColor(idx));
+    if (alpha > max_alpha) {
+      max_alpha = alpha;
+    }
+  }
+  return max_alpha;
+}
+
+// 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* out_err) {
+  if (width < 3 || height < 3) {
+    *out_err = "image must be at least 3x3 (1x1 image with 1 pixel border)";
+    return {};
+  }
+
+  std::vector<Range> horizontal_padding;
+  std::vector<Range> horizontal_layout_bounds;
+  std::vector<Range> vertical_padding;
+  std::vector<Range> vertical_layout_bounds;
+  std::vector<Range> unexpected_ranges;
+  std::unique_ptr<ColorValidator> color_validator;
+
+  if (rows[0][3] == 0) {
+    color_validator = std::make_unique<TransparentNeutralColorValidator>();
+  } else if (PackRGBA(rows[0]) == kColorOpaqueWhite) {
+    color_validator = std::make_unique<WhiteNeutralColorValidator>();
+  } else {
+    *out_err = "top-left corner pixel must be either opaque white or transparent";
+    return {};
+  }
+
+  // Private constructor, can't use make_unique.
+  auto nine_patch = std::unique_ptr<NinePatch>(new NinePatch());
+
+  HorizontalImageLine top_row(rows, 0, 0, width);
+  if (!FillRanges(&top_row, color_validator.get(), &nine_patch->horizontal_stretch_regions,
+                  &unexpected_ranges, out_err)) {
+    return {};
+  }
+
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on top border "
+               << "at x=" << range.start + 1;
+    *out_err = err_stream.str();
+    return {};
+  }
+
+  VerticalImageLine left_col(rows, 0, 0, height);
+  if (!FillRanges(&left_col, color_validator.get(), &nine_patch->vertical_stretch_regions,
+                  &unexpected_ranges, out_err)) {
+    return {};
+  }
+
+  if (!unexpected_ranges.empty()) {
+    const Range& range = unexpected_ranges[0];
+    std::stringstream err_stream;
+    err_stream << "found unexpected optical bounds (red pixel) on left border "
+               << "at y=" << range.start + 1;
+    return {};
+  }
+
+  HorizontalImageLine bottom_row(rows, 0, height - 1, width);
+  if (!FillRanges(&bottom_row, color_validator.get(), &horizontal_padding,
+                  &horizontal_layout_bounds, out_err)) {
+    return {};
+  }
+
+  if (!PopulateBounds(horizontal_padding, horizontal_layout_bounds,
+                      nine_patch->horizontal_stretch_regions, width - 2, &nine_patch->padding.left,
+                      &nine_patch->padding.right, &nine_patch->layout_bounds.left,
+                      &nine_patch->layout_bounds.right, "bottom", out_err)) {
+    return {};
+  }
+
+  VerticalImageLine right_col(rows, width - 1, 0, height);
+  if (!FillRanges(&right_col, color_validator.get(), &vertical_padding, &vertical_layout_bounds,
+                  out_err)) {
+    return {};
+  }
+
+  if (!PopulateBounds(vertical_padding, vertical_layout_bounds,
+                      nine_patch->vertical_stretch_regions, height - 2, &nine_patch->padding.top,
+                      &nine_patch->padding.bottom, &nine_patch->layout_bounds.top,
+                      &nine_patch->layout_bounds.bottom, "right", out_err)) {
+    return {};
+  }
+
+  // Fill the region colors of the 9-patch.
+  const int32_t num_rows = CalculateSegmentCount(nine_patch->horizontal_stretch_regions, width - 2);
+  const int32_t num_cols = CalculateSegmentCount(nine_patch->vertical_stretch_regions, height - 2);
+  if ((int64_t)num_rows * (int64_t)num_cols > 0x7f) {
+    *out_err = "too many regions in 9-patch";
+    return {};
+  }
+
+  nine_patch->region_colors.reserve(num_rows * num_cols);
+  CalculateRegionColors(rows, nine_patch->horizontal_stretch_regions,
+                        nine_patch->vertical_stretch_regions, width - 2, height - 2,
+                        &nine_patch->region_colors);
+
+  // Compute the outline based on opacity.
+
+  // Find left and right extent of 9-patch content on center row.
+  HorizontalImageLine mid_row(rows, 1, height / 2, width - 2);
+  FindOutlineInsets(&mid_row, &nine_patch->outline.left, &nine_patch->outline.right);
+
+  // Find top and bottom extent of 9-patch content on center column.
+  VerticalImageLine mid_col(rows, width / 2, 1, height - 2);
+  FindOutlineInsets(&mid_col, &nine_patch->outline.top, &nine_patch->outline.bottom);
+
+  const int32_t outline_width = (width - 2) - nine_patch->outline.left - nine_patch->outline.right;
+  const int32_t outline_height =
+      (height - 2) - nine_patch->outline.top - nine_patch->outline.bottom;
+
+  // Find the largest alpha value within the outline area.
+  HorizontalImageLine outline_mid_row(rows, 1 + nine_patch->outline.left,
+                                      1 + nine_patch->outline.top + (outline_height / 2),
+                                      outline_width);
+  VerticalImageLine outline_mid_col(rows, 1 + nine_patch->outline.left + (outline_width / 2),
+                                    1 + nine_patch->outline.top, outline_height);
+  nine_patch->outline_alpha =
+      std::max(FindMaxAlpha(&outline_mid_row), FindMaxAlpha(&outline_mid_col));
+
+  // 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 + nine_patch->outline.left, 1 + nine_patch->outline.top, 1, 1,
+                             std::min(outline_width, outline_height));
+  int32_t top_left, bottom_right;
+  FindOutlineInsets(&diagonal, &top_left, &bottom_right);
+
+  /* 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
+   */
+  nine_patch->outline_radius = 3.4142f * top_left;
+  return nine_patch;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeBase(size_t* outLen) const {
+  android::Res_png_9patch data;
+  data.numXDivs = static_cast<uint8_t>(horizontal_stretch_regions.size()) * 2;
+  data.numYDivs = static_cast<uint8_t>(vertical_stretch_regions.size()) * 2;
+  data.numColors = static_cast<uint8_t>(region_colors.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*)horizontal_stretch_regions.data(),
+                                     (const int32_t*)vertical_stretch_regions.data(),
+                                     region_colors.data(), buffer.get());
+  // Convert to file endianness.
+  reinterpret_cast<android::Res_png_9patch*>(buffer.get())->deviceToFile();
+
+  *outLen = data.serializedSize();
+  return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeLayoutBounds(size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 4;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
+  uint8_t* cursor = buffer.get();
+
+  memcpy(cursor, &layout_bounds.left, sizeof(layout_bounds.left));
+  cursor += sizeof(layout_bounds.left);
+
+  memcpy(cursor, &layout_bounds.top, sizeof(layout_bounds.top));
+  cursor += sizeof(layout_bounds.top);
+
+  memcpy(cursor, &layout_bounds.right, sizeof(layout_bounds.right));
+  cursor += sizeof(layout_bounds.right);
+
+  memcpy(cursor, &layout_bounds.bottom, sizeof(layout_bounds.bottom));
+  cursor += sizeof(layout_bounds.bottom);
+
+  *out_len = chunk_len;
+  return buffer;
+}
+
+std::unique_ptr<uint8_t[]> NinePatch::SerializeRoundedRectOutline(size_t* out_len) const {
+  size_t chunk_len = sizeof(uint32_t) * 6;
+  auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[chunk_len]);
+  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) = outline_radius;
+  cursor += sizeof(outline_radius);
+
+  *((uint32_t*)cursor) = outline_alpha;
+
+  *out_len = chunk_len;
+  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;
+}
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
+  for (int i = 0; i < v.size(); ++i) {
+    os << v[i];
+    if (i != v.size() - 1) os << " ";
+  }
+  return os;
+}
+
+::std::ostream& operator<<(::std::ostream& out, const NinePatch& nine_patch) {
+  return out << "horizontalStretch:" << nine_patch.horizontal_stretch_regions
+             << " verticalStretch:" << nine_patch.vertical_stretch_regions
+             << " padding: " << nine_patch.padding << ", bounds: " << nine_patch.layout_bounds
+             << ", outline: " << nine_patch.outline << " rad=" << nine_patch.outline_radius
+             << " alpha=" << nine_patch.outline_alpha;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/Png.cpp b/libs/androidfw/Png.cpp
new file mode 100644
index 0000000..fb45cd9
--- /dev/null
+++ b/libs/androidfw/Png.cpp
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (C) 2015 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 "androidfw/Png.h"
+
+#include <png.h>
+#include <zlib.h>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "android-base/strings.h"
+#include "androidfw/BigBuffer.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/Source.h"
+
+namespace android {
+
+constexpr bool kDebug = false;
+
+struct PngInfo {
+  ~PngInfo() {
+    for (png_bytep row : rows) {
+      if (row != nullptr) {
+        delete[] row;
+      }
+    }
+
+    delete[] xDivs;
+    delete[] yDivs;
+  }
+
+  void* serialize9Patch() {
+    void* serialized = Res_png_9patch::serialize(info9Patch, xDivs, yDivs, colors.data());
+    reinterpret_cast<Res_png_9patch*>(serialized)->deviceToFile();
+    return serialized;
+  }
+
+  uint32_t width = 0;
+  uint32_t height = 0;
+  std::vector<png_bytep> rows;
+
+  bool is9Patch = false;
+  Res_png_9patch info9Patch;
+  int32_t* xDivs = nullptr;
+  int32_t* yDivs = nullptr;
+  std::vector<uint32_t> colors;
+
+  // Layout padding.
+  bool haveLayoutBounds = false;
+  int32_t layoutBoundsLeft;
+  int32_t layoutBoundsTop;
+  int32_t layoutBoundsRight;
+  int32_t layoutBoundsBottom;
+
+  // Round rect outline description.
+  int32_t outlineInsetsLeft;
+  int32_t outlineInsetsTop;
+  int32_t outlineInsetsRight;
+  int32_t outlineInsetsBottom;
+  float outlineRadius;
+  uint8_t outlineAlpha;
+};
+
+static void readDataFromStream(png_structp readPtr, png_bytep data, png_size_t length) {
+  std::istream* input = reinterpret_cast<std::istream*>(png_get_io_ptr(readPtr));
+  if (!input->read(reinterpret_cast<char*>(data), length)) {
+    png_error(readPtr, strerror(errno));
+  }
+}
+
+static void writeDataToStream(png_structp writePtr, png_bytep data, png_size_t length) {
+  BigBuffer* outBuffer = reinterpret_cast<BigBuffer*>(png_get_io_ptr(writePtr));
+  png_bytep buf = outBuffer->NextBlock<png_byte>(length);
+  memcpy(buf, data, length);
+}
+
+static void flushDataToStream(png_structp /*writePtr*/) {
+}
+
+static void logWarning(png_structp readPtr, png_const_charp warningMessage) {
+  IDiagnostics* diag = reinterpret_cast<IDiagnostics*>(png_get_error_ptr(readPtr));
+  diag->Warn(DiagMessage() << warningMessage);
+}
+
+static bool readPng(IDiagnostics* diag, png_structp readPtr, png_infop infoPtr, PngInfo* outInfo) {
+  if (setjmp(png_jmpbuf(readPtr))) {
+    diag->Error(DiagMessage() << "failed reading png");
+    return false;
+  }
+
+  png_set_sig_bytes(readPtr, kPngSignatureSize);
+  png_read_info(readPtr, infoPtr);
+
+  int colorType, bitDepth, interlaceType, compressionType;
+  png_get_IHDR(readPtr, infoPtr, &outInfo->width, &outInfo->height, &bitDepth, &colorType,
+               &interlaceType, &compressionType, nullptr);
+
+  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);
+  }
+
+  png_set_interlace_handling(readPtr);
+  png_read_update_info(readPtr, infoPtr);
+
+  const uint32_t rowBytes = png_get_rowbytes(readPtr, infoPtr);
+  outInfo->rows.resize(outInfo->height);
+  for (size_t i = 0; i < outInfo->height; i++) {
+    outInfo->rows[i] = new png_byte[rowBytes];
+  }
+
+  png_read_image(readPtr, outInfo->rows.data());
+  png_read_end(readPtr, infoPtr);
+  return true;
+}
+
+static void checkNinePatchSerialization(Res_png_9patch* inPatch, void* data) {
+  size_t patchSize = inPatch->serializedSize();
+  void* newData = malloc(patchSize);
+  memcpy(newData, data, patchSize);
+  Res_png_9patch* outPatch = inPatch->deserialize(newData);
+  outPatch->fileToDevice();
+  // deserialization is done in place, so outPatch == newData
+  assert(outPatch == newData);
+  assert(outPatch->numXDivs == inPatch->numXDivs);
+  assert(outPatch->numYDivs == inPatch->numYDivs);
+  assert(outPatch->paddingLeft == inPatch->paddingLeft);
+  assert(outPatch->paddingRight == inPatch->paddingRight);
+  assert(outPatch->paddingTop == inPatch->paddingTop);
+  assert(outPatch->paddingBottom == inPatch->paddingBottom);
+  /*    for (int i = 0; i < outPatch->numXDivs; i++) {
+          assert(outPatch->getXDivs()[i] == inPatch->getXDivs()[i]);
+      }
+      for (int i = 0; i < outPatch->numYDivs; i++) {
+          assert(outPatch->getYDivs()[i] == inPatch->getYDivs()[i]);
+      }
+      for (int i = 0; i < outPatch->numColors; i++) {
+          assert(outPatch->getColors()[i] == inPatch->getColors()[i]);
+      }*/
+  free(newData);
+}
+
+/*static void dump_image(int w, int h, const png_byte* const* rows, int
+color_type) {
+    int i, j, rr, gg, bb, aa;
+
+    int bpp;
+    if (color_type == PNG_COLOR_TYPE_PALETTE || color_type ==
+PNG_COLOR_TYPE_GRAY) {
+        bpp = 1;
+    } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+        bpp = 2;
+    } else if (color_type == PNG_COLOR_TYPE_RGB || color_type ==
+PNG_COLOR_TYPE_RGB_ALPHA) {
+        // We use a padding byte even when there is no alpha
+        bpp = 4;
+    } else {
+        printf("Unknown color type %d.\n", color_type);
+    }
+
+    for (j = 0; j < h; j++) {
+        const png_byte* row = rows[j];
+        for (i = 0; i < w; i++) {
+            rr = row[0];
+            gg = row[1];
+            bb = row[2];
+            aa = row[3];
+            row += bpp;
+
+            if (i == 0) {
+                printf("Row %d:", j);
+            }
+            switch (bpp) {
+            case 1:
+                printf(" (%d)", rr);
+                break;
+            case 2:
+                printf(" (%d %d", rr, gg);
+                break;
+            case 3:
+                printf(" (%d %d %d)", rr, gg, bb);
+                break;
+            case 4:
+                printf(" (%d %d %d %d)", rr, gg, bb, aa);
+                break;
+            }
+            if (i == (w - 1)) {
+                printf("\n");
+            }
+        }
+    }
+}*/
+
+#ifdef MAX
+#undef MAX
+#endif
+#ifdef ABS
+#undef ABS
+#endif
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ABS(a) ((a) < 0 ? -(a) : (a))
+
+static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo, int grayscaleTolerance,
+                          png_colorp rgbPalette, png_bytep alphaPalette, int* paletteEntries,
+                          bool* hasTransparency, int* colorType, png_bytepp outRows) {
+  int w = imageInfo.width;
+  int h = imageInfo.height;
+  int i, j, rr, gg, bb, aa, idx;
+  uint32_t colors[256], col;
+  int num_colors = 0;
+  int maxGrayDeviation = 0;
+
+  bool isOpaque = true;
+  bool isPalette = true;
+  bool isGrayscale = true;
+
+  // 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
+
+  if (kDebug) {
+    printf("Initial image data:\n");
+    // dump_image(w, h, imageInfo.rows.data(), PNG_COLOR_TYPE_RGB_ALPHA);
+  }
+
+  for (j = 0; j < h; j++) {
+    const png_byte* row = imageInfo.rows[j];
+    png_bytep out = outRows[j];
+    for (i = 0; i < w; i++) {
+      rr = *row++;
+      gg = *row++;
+      bb = *row++;
+      aa = *row++;
+
+      int odev = maxGrayDeviation;
+      maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);
+      maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);
+      maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);
+      if (maxGrayDeviation > odev) {
+        if (kDebug) {
+          printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n", maxGrayDeviation, i, j,
+                 rr, gg, bb, aa);
+        }
+      }
+
+      // Check if image is really grayscale
+      if (isGrayscale) {
+        if (rr != gg || rr != bb) {
+          if (kDebug) {
+            printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n", i, j, rr, gg, bb, aa);
+          }
+          isGrayscale = false;
+        }
+      }
+
+      // Check if image is really opaque
+      if (isOpaque) {
+        if (aa != 0xff) {
+          if (kDebug) {
+            printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n", i, j, rr, gg, bb, aa);
+          }
+          isOpaque = false;
+        }
+      }
+
+      // Check if image is really <= 256 colors
+      if (isPalette) {
+        col = (uint32_t)((rr << 24) | (gg << 16) | (bb << 8) | aa);
+        bool match = false;
+        for (idx = 0; idx < num_colors; idx++) {
+          if (colors[idx] == col) {
+            match = true;
+            break;
+          }
+        }
+
+        // Write the palette index for the pixel to outRows optimistically
+        // We might overwrite it later if we decide to encode as gray or
+        // gray + alpha
+        *out++ = idx;
+        if (!match) {
+          if (num_colors == 256) {
+            if (kDebug) {
+              printf("Found 257th color at %d, %d\n", i, j);
+            }
+            isPalette = false;
+          } else {
+            colors[num_colors++] = col;
+          }
+        }
+      }
+    }
+  }
+
+  *paletteEntries = 0;
+  *hasTransparency = !isOpaque;
+  int bpp = isOpaque ? 3 : 4;
+  int paletteSize = w * h + bpp * num_colors;
+
+  if (kDebug) {
+    printf("isGrayscale = %s\n", isGrayscale ? "true" : "false");
+    printf("isOpaque = %s\n", isOpaque ? "true" : "false");
+    printf("isPalette = %s\n", isPalette ? "true" : "false");
+    printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n", paletteSize, 2 * w * h,
+           bpp * w * h);
+    printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation, grayscaleTolerance);
+  }
+
+  // Choose the best color type for the image.
+  // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel
+  // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct
+  // combinations
+  //     is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA
+  // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is
+  // sufficiently
+  //     small, otherwise use COLOR_TYPE_RGB{_ALPHA}
+  if (isGrayscale) {
+    if (isOpaque) {
+      *colorType = PNG_COLOR_TYPE_GRAY;  // 1 byte/pixel
+    } else {
+      // Use a simple heuristic to determine whether using a palette will
+      // save space versus using gray + alpha for each pixel.
+      // This doesn't take into account chunk overhead, filtering, LZ
+      // compression, etc.
+      if (isPalette && (paletteSize < 2 * w * h)) {
+        *colorType = PNG_COLOR_TYPE_PALETTE;  // 1 byte/pixel + 4 bytes/color
+      } else {
+        *colorType = PNG_COLOR_TYPE_GRAY_ALPHA;  // 2 bytes per pixel
+      }
+    }
+  } else if (isPalette && (paletteSize < bpp * w * h)) {
+    *colorType = PNG_COLOR_TYPE_PALETTE;
+  } else {
+    if (maxGrayDeviation <= grayscaleTolerance) {
+      diag->Note(DiagMessage() << "forcing image to gray (max deviation = " << maxGrayDeviation
+                               << ")");
+      *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;
+    } else {
+      *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+    }
+  }
+
+  // Perform postprocessing of the image or palette data based on the final
+  // color type chosen
+
+  if (*colorType == PNG_COLOR_TYPE_PALETTE) {
+    // Create separate RGB and Alpha palettes and set the number of colors
+    *paletteEntries = num_colors;
+
+    // Create the RGB and alpha palettes
+    for (int idx = 0; idx < num_colors; idx++) {
+      col = colors[idx];
+      rgbPalette[idx].red = (png_byte)((col >> 24) & 0xff);
+      rgbPalette[idx].green = (png_byte)((col >> 16) & 0xff);
+      rgbPalette[idx].blue = (png_byte)((col >> 8) & 0xff);
+      alphaPalette[idx] = (png_byte)(col & 0xff);
+    }
+  } else if (*colorType == PNG_COLOR_TYPE_GRAY || *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    // If the image is gray or gray + alpha, compact the pixels into outRows
+    for (j = 0; j < h; j++) {
+      const png_byte* row = imageInfo.rows[j];
+      png_bytep out = outRows[j];
+      for (i = 0; i < w; i++) {
+        rr = *row++;
+        gg = *row++;
+        bb = *row++;
+        aa = *row++;
+
+        if (isGrayscale) {
+          *out++ = rr;
+        } else {
+          *out++ = (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
+        }
+        if (!isOpaque) {
+          *out++ = aa;
+        }
+      }
+    }
+  }
+}
+
+static bool writePng(IDiagnostics* diag, png_structp writePtr, png_infop infoPtr, PngInfo* info,
+                     int grayScaleTolerance) {
+  if (setjmp(png_jmpbuf(writePtr))) {
+    diag->Error(DiagMessage() << "failed to write png");
+    return false;
+  }
+
+  uint32_t width, height;
+  int colorType, bitDepth, interlaceType, compressionType;
+
+  png_unknown_chunk unknowns[3];
+  unknowns[0].data = nullptr;
+  unknowns[1].data = nullptr;
+  unknowns[2].data = nullptr;
+
+  png_bytepp outRows = (png_bytepp)malloc((int)info->height * sizeof(png_bytep));
+  if (outRows == (png_bytepp)0) {
+    printf("Can't allocate output buffer!\n");
+    exit(1);
+  }
+  for (uint32_t i = 0; i < info->height; i++) {
+    outRows[i] = (png_bytep)malloc(2 * (int)info->width);
+    if (outRows[i] == (png_bytep)0) {
+      printf("Can't allocate output buffer!\n");
+      exit(1);
+    }
+  }
+
+  png_set_compression_level(writePtr, Z_BEST_COMPRESSION);
+
+  if (kDebug) {
+    diag->Note(DiagMessage() << "writing image: w = " << info->width << ", h = " << info->height);
+  }
+
+  png_color rgbPalette[256];
+  png_byte alphaPalette[256];
+  bool hasTransparency;
+  int paletteEntries;
+
+  analyze_image(diag, *info, grayScaleTolerance, rgbPalette, alphaPalette, &paletteEntries,
+                &hasTransparency, &colorType, outRows);
+
+  // If the image is a 9-patch, we need to preserve it as a ARGB file to make
+  // sure the pixels will not be pre-dithered/clamped until we decide they are
+  if (info->is9Patch && (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY ||
+                         colorType == PNG_COLOR_TYPE_PALETTE)) {
+    colorType = PNG_COLOR_TYPE_RGB_ALPHA;
+  }
+
+  if (kDebug) {
+    switch (colorType) {
+      case PNG_COLOR_TYPE_PALETTE:
+        diag->Note(DiagMessage() << "has " << paletteEntries << " colors"
+                                 << (hasTransparency ? " (with alpha)" : "")
+                                 << ", using PNG_COLOR_TYPE_PALLETTE");
+        break;
+      case PNG_COLOR_TYPE_GRAY:
+        diag->Note(DiagMessage() << "is opaque gray, using PNG_COLOR_TYPE_GRAY");
+        break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+        diag->Note(DiagMessage() << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
+        break;
+      case PNG_COLOR_TYPE_RGB:
+        diag->Note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
+        break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+        diag->Note(DiagMessage() << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA");
+        break;
+    }
+  }
+
+  png_set_IHDR(writePtr, infoPtr, info->width, info->height, 8, colorType, PNG_INTERLACE_NONE,
+               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+  if (colorType == PNG_COLOR_TYPE_PALETTE) {
+    png_set_PLTE(writePtr, infoPtr, rgbPalette, paletteEntries);
+    if (hasTransparency) {
+      png_set_tRNS(writePtr, infoPtr, alphaPalette, paletteEntries, (png_color_16p)0);
+    }
+    png_set_filter(writePtr, 0, PNG_NO_FILTERS);
+  } else {
+    png_set_filter(writePtr, 0, PNG_ALL_FILTERS);
+  }
+
+  if (info->is9Patch) {
+    int chunkCount = 2 + (info->haveLayoutBounds ? 1 : 0);
+    int pIndex = info->haveLayoutBounds ? 2 : 1;
+    int bIndex = 1;
+    int oIndex = 0;
+
+    // Chunks ordered thusly because older platforms depend on the base 9 patch
+    // data being last
+    png_bytep chunkNames =
+        info->haveLayoutBounds ? (png_bytep) "npOl\0npLb\0npTc\0" : (png_bytep) "npOl\0npTc";
+
+    // base 9 patch data
+    if (kDebug) {
+      diag->Note(DiagMessage() << "adding 9-patch info..");
+    }
+    memcpy((char*)unknowns[pIndex].name, "npTc", 5);
+    unknowns[pIndex].data = (png_byte*)info->serialize9Patch();
+    unknowns[pIndex].size = info->info9Patch.serializedSize();
+    // TODO: remove the check below when everything works
+    checkNinePatchSerialization(&info->info9Patch, unknowns[pIndex].data);
+
+    // automatically generated 9 patch outline data
+    int chunkSize = sizeof(png_uint_32) * 6;
+    memcpy((char*)unknowns[oIndex].name, "npOl", 5);
+    unknowns[oIndex].data = (png_byte*)calloc(chunkSize, 1);
+    png_byte outputData[chunkSize];
+    memcpy(&outputData, &info->outlineInsetsLeft, 4 * sizeof(png_uint_32));
+    ((float*)outputData)[4] = info->outlineRadius;
+    ((png_uint_32*)outputData)[5] = info->outlineAlpha;
+    memcpy(unknowns[oIndex].data, &outputData, chunkSize);
+    unknowns[oIndex].size = chunkSize;
+
+    // optional optical inset / layout bounds data
+    if (info->haveLayoutBounds) {
+      int chunkSize = sizeof(png_uint_32) * 4;
+      memcpy((char*)unknowns[bIndex].name, "npLb", 5);
+      unknowns[bIndex].data = (png_byte*)calloc(chunkSize, 1);
+      memcpy(unknowns[bIndex].data, &info->layoutBoundsLeft, chunkSize);
+      unknowns[bIndex].size = chunkSize;
+    }
+
+    for (int i = 0; i < chunkCount; i++) {
+      unknowns[i].location = PNG_HAVE_PLTE;
+    }
+    png_set_keep_unknown_chunks(writePtr, PNG_HANDLE_CHUNK_ALWAYS, chunkNames, chunkCount);
+    png_set_unknown_chunks(writePtr, infoPtr, unknowns, chunkCount);
+
+#if PNG_LIBPNG_VER < 10600
+    // Deal with unknown chunk location bug in 1.5.x and earlier.
+    png_set_unknown_chunk_location(writePtr, infoPtr, 0, PNG_HAVE_PLTE);
+    if (info->haveLayoutBounds) {
+      png_set_unknown_chunk_location(writePtr, infoPtr, 1, PNG_HAVE_PLTE);
+    }
+#endif
+  }
+
+  png_write_info(writePtr, infoPtr);
+
+  png_bytepp rows;
+  if (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
+    if (colorType == PNG_COLOR_TYPE_RGB) {
+      png_set_filler(writePtr, 0, PNG_FILLER_AFTER);
+    }
+    rows = info->rows.data();
+  } else {
+    rows = outRows;
+  }
+  png_write_image(writePtr, rows);
+
+  if (kDebug) {
+    printf("Final image data:\n");
+    // dump_image(info->width, info->height, rows, colorType);
+  }
+
+  png_write_end(writePtr, infoPtr);
+
+  for (uint32_t i = 0; i < info->height; i++) {
+    free(outRows[i]);
+  }
+  free(outRows);
+  free(unknowns[0].data);
+  free(unknowns[1].data);
+  free(unknowns[2].data);
+
+  png_get_IHDR(writePtr, infoPtr, &width, &height, &bitDepth, &colorType, &interlaceType,
+               &compressionType, nullptr);
+
+  if (kDebug) {
+    diag->Note(DiagMessage() << "image written: w = " << width << ", h = " << height
+                             << ", d = " << bitDepth << ", colors = " << colorType
+                             << ", inter = " << interlaceType << ", comp = " << compressionType);
+  }
+  return true;
+}
+
+constexpr uint32_t kColorWhite = 0xffffffffu;
+constexpr uint32_t kColorTick = 0xff000000u;
+constexpr uint32_t kColorLayoutBoundsTick = 0xff0000ffu;
+
+enum class TickType { kNone, kTick, kLayoutBounds, kBoth };
+
+static TickType tickType(png_bytep p, bool transparent, const char** outError) {
+  png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+
+  if (transparent) {
+    if (p[3] == 0) {
+      return TickType::kNone;
+    }
+    if (color == kColorLayoutBoundsTick) {
+      return TickType::kLayoutBounds;
+    }
+    if (color == kColorTick) {
+      return TickType::kTick;
+    }
+
+    // Error cases
+    if (p[3] != 0xff) {
+      *outError =
+          "Frame pixels must be either solid or transparent "
+          "(not intermediate alphas)";
+      return TickType::kNone;
+    }
+
+    if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
+      *outError = "Ticks in transparent frame must be black or red";
+    }
+    return TickType::kTick;
+  }
+
+  if (p[3] != 0xFF) {
+    *outError = "White frame must be a solid color (no alpha)";
+  }
+  if (color == kColorWhite) {
+    return TickType::kNone;
+  }
+  if (color == kColorTick) {
+    return TickType::kTick;
+  }
+  if (color == kColorLayoutBoundsTick) {
+    return TickType::kLayoutBounds;
+  }
+
+  if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
+    *outError = "Ticks in white frame must be black or red";
+    return TickType::kNone;
+  }
+  return TickType::kTick;
+}
+
+enum class TickState { kStart, kInside1, kOutside1 };
+
+static bool getHorizontalTicks(png_bytep row, int width, bool transparent, bool required,
+                               int32_t* outLeft, int32_t* outRight, const char** outError,
+                               uint8_t* outDivs, bool multipleAllowed) {
+  *outLeft = *outRight = -1;
+  TickState state = TickState::kStart;
+  bool found = false;
+
+  for (int i = 1; i < width - 1; i++) {
+    if (tickType(row + i * 4, transparent, outError) == TickType::kTick) {
+      if (state == TickState::kStart || (state == TickState::kOutside1 && multipleAllowed)) {
+        *outLeft = i - 1;
+        *outRight = width - 2;
+        found = true;
+        if (outDivs != NULL) {
+          *outDivs += 2;
+        }
+        state = TickState::kInside1;
+      } else if (state == TickState::kOutside1) {
+        *outError = "Can't have more than one marked region along edge";
+        *outLeft = i;
+        return false;
+      }
+    } else if (!*outError) {
+      if (state == TickState::kInside1) {
+        // We're done with this div.  Move on to the next.
+        *outRight = i - 1;
+        outRight += 2;
+        outLeft += 2;
+        state = TickState::kOutside1;
+      }
+    } else {
+      *outLeft = i;
+      return false;
+    }
+  }
+
+  if (required && !found) {
+    *outError = "No marked region found along edge";
+    *outLeft = -1;
+    return false;
+  }
+  return true;
+}
+
+static bool getVerticalTicks(png_bytepp rows, int offset, int height, bool transparent,
+                             bool required, int32_t* outTop, int32_t* outBottom,
+                             const char** outError, uint8_t* outDivs, bool multipleAllowed) {
+  *outTop = *outBottom = -1;
+  TickState state = TickState::kStart;
+  bool found = false;
+
+  for (int i = 1; i < height - 1; i++) {
+    if (tickType(rows[i] + offset, transparent, outError) == TickType::kTick) {
+      if (state == TickState::kStart || (state == TickState::kOutside1 && multipleAllowed)) {
+        *outTop = i - 1;
+        *outBottom = height - 2;
+        found = true;
+        if (outDivs != NULL) {
+          *outDivs += 2;
+        }
+        state = TickState::kInside1;
+      } else if (state == TickState::kOutside1) {
+        *outError = "Can't have more than one marked region along edge";
+        *outTop = i;
+        return false;
+      }
+    } else if (!*outError) {
+      if (state == TickState::kInside1) {
+        // We're done with this div.  Move on to the next.
+        *outBottom = i - 1;
+        outTop += 2;
+        outBottom += 2;
+        state = TickState::kOutside1;
+      }
+    } else {
+      *outTop = i;
+      return false;
+    }
+  }
+
+  if (required && !found) {
+    *outError = "No marked region found along edge";
+    *outTop = -1;
+    return false;
+  }
+  return true;
+}
+
+static bool getHorizontalLayoutBoundsTicks(png_bytep row, int width, bool transparent,
+                                           bool /* required */, int32_t* outLeft, int32_t* outRight,
+                                           const char** outError) {
+  *outLeft = *outRight = 0;
+
+  // Look for left tick
+  if (tickType(row + 4, transparent, outError) == TickType::kLayoutBounds) {
+    // Starting with a layout padding tick
+    int i = 1;
+    while (i < width - 1) {
+      (*outLeft)++;
+      i++;
+      if (tickType(row + i * 4, transparent, outError) != TickType::kLayoutBounds) {
+        break;
+      }
+    }
+  }
+
+  // Look for right tick
+  if (tickType(row + (width - 2) * 4, transparent, outError) == TickType::kLayoutBounds) {
+    // Ending with a layout padding tick
+    int i = width - 2;
+    while (i > 1) {
+      (*outRight)++;
+      i--;
+      if (tickType(row + i * 4, transparent, outError) != TickType::kLayoutBounds) {
+        break;
+      }
+    }
+  }
+  return true;
+}
+
+static bool getVerticalLayoutBoundsTicks(png_bytepp rows, int offset, int height, bool transparent,
+                                         bool /* required */, int32_t* outTop, int32_t* outBottom,
+                                         const char** outError) {
+  *outTop = *outBottom = 0;
+
+  // Look for top tick
+  if (tickType(rows[1] + offset, transparent, outError) == TickType::kLayoutBounds) {
+    // Starting with a layout padding tick
+    int i = 1;
+    while (i < height - 1) {
+      (*outTop)++;
+      i++;
+      if (tickType(rows[i] + offset, transparent, outError) != TickType::kLayoutBounds) {
+        break;
+      }
+    }
+  }
+
+  // Look for bottom tick
+  if (tickType(rows[height - 2] + offset, transparent, outError) == TickType::kLayoutBounds) {
+    // Ending with a layout padding tick
+    int i = height - 2;
+    while (i > 1) {
+      (*outBottom)++;
+      i--;
+      if (tickType(rows[i] + offset, transparent, outError) != TickType::kLayoutBounds) {
+        break;
+      }
+    }
+  }
+  return true;
+}
+
+static void findMaxOpacity(png_bytepp rows, int startX, int startY, int endX, int endY, int dX,
+                           int dY, int* outInset) {
+  uint8_t maxOpacity = 0;
+  int inset = 0;
+  *outInset = 0;
+  for (int x = startX, y = startY; x != endX && y != endY; x += dX, y += dY, inset++) {
+    png_byte* color = rows[y] + x * 4;
+    uint8_t opacity = color[3];
+    if (opacity > maxOpacity) {
+      maxOpacity = opacity;
+      *outInset = inset;
+    }
+    if (opacity == 0xff) return;
+  }
+}
+
+static uint8_t maxAlphaOverRow(png_bytep row, int startX, int endX) {
+  uint8_t maxAlpha = 0;
+  for (int x = startX; x < endX; x++) {
+    uint8_t alpha = (row + x * 4)[3];
+    if (alpha > maxAlpha) maxAlpha = alpha;
+  }
+  return maxAlpha;
+}
+
+static uint8_t maxAlphaOverCol(png_bytepp rows, int offsetX, int startY, int endY) {
+  uint8_t maxAlpha = 0;
+  for (int y = startY; y < endY; y++) {
+    uint8_t alpha = (rows[y] + offsetX * 4)[3];
+    if (alpha > maxAlpha) maxAlpha = alpha;
+  }
+  return maxAlpha;
+}
+
+static void getOutline(PngInfo* image) {
+  int midX = image->width / 2;
+  int midY = image->height / 2;
+  int endX = image->width - 2;
+  int endY = image->height - 2;
+
+  // find left and right extent of nine patch content on center row
+  if (image->width > 4) {
+    findMaxOpacity(image->rows.data(), 1, midY, midX, -1, 1, 0, &image->outlineInsetsLeft);
+    findMaxOpacity(image->rows.data(), endX, midY, midX, -1, -1, 0, &image->outlineInsetsRight);
+  } else {
+    image->outlineInsetsLeft = 0;
+    image->outlineInsetsRight = 0;
+  }
+
+  // find top and bottom extent of nine patch content on center column
+  if (image->height > 4) {
+    findMaxOpacity(image->rows.data(), midX, 1, -1, midY, 0, 1, &image->outlineInsetsTop);
+    findMaxOpacity(image->rows.data(), midX, endY, -1, midY, 0, -1, &image->outlineInsetsBottom);
+  } else {
+    image->outlineInsetsTop = 0;
+    image->outlineInsetsBottom = 0;
+  }
+
+  int innerStartX = 1 + image->outlineInsetsLeft;
+  int innerStartY = 1 + image->outlineInsetsTop;
+  int innerEndX = endX - image->outlineInsetsRight;
+  int innerEndY = endY - image->outlineInsetsBottom;
+  int innerMidX = (innerEndX + innerStartX) / 2;
+  int innerMidY = (innerEndY + innerStartY) / 2;
+
+  // assuming the image is a round rect, compute the radius by marching
+  // diagonally from the top left corner towards the center
+  image->outlineAlpha =
+      std::max(maxAlphaOverRow(image->rows[innerMidY], innerStartX, innerEndX),
+               maxAlphaOverCol(image->rows.data(), innerMidX, innerStartY, innerStartY));
+
+  int diagonalInset = 0;
+  findMaxOpacity(image->rows.data(), innerStartX, innerStartY, innerMidX, innerMidY, 1, 1,
+                 &diagonalInset);
+
+  /* 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
+   */
+  image->outlineRadius = 3.4142f * diagonalInset;
+
+  if (kDebug) {
+    printf("outline insets %d %d %d %d, rad %f, alpha %x\n", image->outlineInsetsLeft,
+           image->outlineInsetsTop, image->outlineInsetsRight, image->outlineInsetsBottom,
+           image->outlineRadius, image->outlineAlpha);
+  }
+}
+
+static uint32_t getColor(png_bytepp rows, int left, int top, int right, int bottom) {
+  png_bytep color = rows[top] + left * 4;
+
+  if (left > right || top > bottom) {
+    return Res_png_9patch::TRANSPARENT_COLOR;
+  }
+
+  while (top <= bottom) {
+    for (int i = left; i <= right; i++) {
+      png_bytep p = rows[top] + i * 4;
+      if (color[3] == 0) {
+        if (p[3] != 0) {
+          return Res_png_9patch::NO_COLOR;
+        }
+      } else if (p[0] != color[0] || p[1] != color[1] || p[2] != color[2] || p[3] != color[3]) {
+        return Res_png_9patch::NO_COLOR;
+      }
+    }
+    top++;
+  }
+
+  if (color[3] == 0) {
+    return Res_png_9patch::TRANSPARENT_COLOR;
+  }
+  return (color[3] << 24) | (color[0] << 16) | (color[1] << 8) | color[2];
+}
+
+static bool do9Patch(PngInfo* image, std::string* outError) {
+  image->is9Patch = true;
+
+  int W = image->width;
+  int H = image->height;
+  int i, j;
+
+  const int maxSizeXDivs = W * sizeof(int32_t);
+  const int maxSizeYDivs = H * sizeof(int32_t);
+  int32_t* xDivs = image->xDivs = new int32_t[W];
+  int32_t* yDivs = image->yDivs = new int32_t[H];
+  uint8_t numXDivs = 0;
+  uint8_t numYDivs = 0;
+
+  int8_t numColors;
+  int numRows;
+  int numCols;
+  int top;
+  int left;
+  int right;
+  int bottom;
+  memset(xDivs, -1, maxSizeXDivs);
+  memset(yDivs, -1, maxSizeYDivs);
+  image->info9Patch.paddingLeft = image->info9Patch.paddingRight = -1;
+  image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1;
+  image->layoutBoundsLeft = image->layoutBoundsRight = 0;
+  image->layoutBoundsTop = image->layoutBoundsBottom = 0;
+
+  png_bytep p = image->rows[0];
+  bool transparent = p[3] == 0;
+  bool hasColor = false;
+
+  const char* errorMsg = nullptr;
+  int errorPixel = -1;
+  const char* errorEdge = nullptr;
+
+  int colorIndex = 0;
+  std::vector<png_bytep> newRows;
+
+  // Validate size...
+  if (W < 3 || H < 3) {
+    errorMsg = "Image must be at least 3x3 (1x1 without frame) pixels";
+    goto getout;
+  }
+
+  // Validate frame...
+  if (!transparent && (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) {
+    errorMsg = "Must have one-pixel frame that is either transparent or white";
+    goto getout;
+  }
+
+  // Find left and right of sizing areas...
+  if (!getHorizontalTicks(p, W, transparent, true, &xDivs[0], &xDivs[1], &errorMsg, &numXDivs,
+                          true)) {
+    errorPixel = xDivs[0];
+    errorEdge = "top";
+    goto getout;
+  }
+
+  // Find top and bottom of sizing areas...
+  if (!getVerticalTicks(image->rows.data(), 0, H, transparent, true, &yDivs[0], &yDivs[1],
+                        &errorMsg, &numYDivs, true)) {
+    errorPixel = yDivs[0];
+    errorEdge = "left";
+    goto getout;
+  }
+
+  // Copy patch size data into image...
+  image->info9Patch.numXDivs = numXDivs;
+  image->info9Patch.numYDivs = numYDivs;
+
+  // Find left and right of padding area...
+  if (!getHorizontalTicks(image->rows[H - 1], W, transparent, false, &image->info9Patch.paddingLeft,
+                          &image->info9Patch.paddingRight, &errorMsg, nullptr, false)) {
+    errorPixel = image->info9Patch.paddingLeft;
+    errorEdge = "bottom";
+    goto getout;
+  }
+
+  // Find top and bottom of padding area...
+  if (!getVerticalTicks(image->rows.data(), (W - 1) * 4, H, transparent, false,
+                        &image->info9Patch.paddingTop, &image->info9Patch.paddingBottom, &errorMsg,
+                        nullptr, false)) {
+    errorPixel = image->info9Patch.paddingTop;
+    errorEdge = "right";
+    goto getout;
+  }
+
+  // Find left and right of layout padding...
+  getHorizontalLayoutBoundsTicks(image->rows[H - 1], W, transparent, false,
+                                 &image->layoutBoundsLeft, &image->layoutBoundsRight, &errorMsg);
+
+  getVerticalLayoutBoundsTicks(image->rows.data(), (W - 1) * 4, H, transparent, false,
+                               &image->layoutBoundsTop, &image->layoutBoundsBottom, &errorMsg);
+
+  image->haveLayoutBounds = image->layoutBoundsLeft != 0 || image->layoutBoundsRight != 0 ||
+                            image->layoutBoundsTop != 0 || image->layoutBoundsBottom != 0;
+
+  if (image->haveLayoutBounds) {
+    if (kDebug) {
+      printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft, image->layoutBoundsTop,
+             image->layoutBoundsRight, image->layoutBoundsBottom);
+    }
+  }
+
+  // use opacity of pixels to estimate the round rect outline
+  getOutline(image);
+
+  // If padding is not yet specified, take values from size.
+  if (image->info9Patch.paddingLeft < 0) {
+    image->info9Patch.paddingLeft = xDivs[0];
+    image->info9Patch.paddingRight = W - 2 - xDivs[1];
+  } else {
+    // Adjust value to be correct!
+    image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight;
+  }
+  if (image->info9Patch.paddingTop < 0) {
+    image->info9Patch.paddingTop = yDivs[0];
+    image->info9Patch.paddingBottom = H - 2 - yDivs[1];
+  } else {
+    // Adjust value to be correct!
+    image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;
+  }
+
+  /*    if (kDebug) {
+          printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName,
+                  xDivs[0], xDivs[1],
+                  yDivs[0], yDivs[1]);
+          printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName,
+                  image->info9Patch.paddingLeft, image->info9Patch.paddingRight,
+                  image->info9Patch.paddingTop,
+     image->info9Patch.paddingBottom);
+      }*/
+
+  // Remove frame from image.
+  newRows.resize(H - 2);
+  for (i = 0; i < H - 2; i++) {
+    newRows[i] = image->rows[i + 1];
+    memmove(newRows[i], newRows[i] + 4, (W - 2) * 4);
+  }
+  image->rows.swap(newRows);
+
+  image->width -= 2;
+  W = image->width;
+  image->height -= 2;
+  H = image->height;
+
+  // Figure out the number of rows and columns in the N-patch
+  numCols = numXDivs + 1;
+  if (xDivs[0] == 0) {  // Column 1 is strechable
+    numCols--;
+  }
+  if (xDivs[numXDivs - 1] == W) {
+    numCols--;
+  }
+  numRows = numYDivs + 1;
+  if (yDivs[0] == 0) {  // Row 1 is strechable
+    numRows--;
+  }
+  if (yDivs[numYDivs - 1] == H) {
+    numRows--;
+  }
+
+  // Make sure the amount of rows and columns will fit in the number of
+  // colors we can use in the 9-patch format.
+  if (numRows * numCols > 0x7F) {
+    errorMsg = "Too many rows and columns in 9-patch perimeter";
+    goto getout;
+  }
+
+  numColors = numRows * numCols;
+  image->info9Patch.numColors = numColors;
+  image->colors.resize(numColors);
+
+  // Fill in color information for each patch.
+
+  uint32_t c;
+  top = 0;
+
+  // The first row always starts with the top being at y=0 and the bottom
+  // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case
+  // the first row is stretchable along the Y axis, otherwise it is fixed.
+  // The last row always ends with the bottom being bitmap.height and the top
+  // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
+  // yDivs[numYDivs-1]. In the former case the last row is stretchable along
+  // the Y axis, otherwise it is fixed.
+  //
+  // The first and last columns are similarly treated with respect to the X
+  // axis.
+  //
+  // The above is to help explain some of the special casing that goes on the
+  // code below.
+
+  // The initial yDiv and whether the first row is considered stretchable or
+  // not depends on whether yDiv[0] was zero or not.
+  for (j = (yDivs[0] == 0 ? 1 : 0); j <= numYDivs && top < H; j++) {
+    if (j == numYDivs) {
+      bottom = H;
+    } else {
+      bottom = yDivs[j];
+    }
+    left = 0;
+    // The initial xDiv and whether the first column is considered
+    // stretchable or not depends on whether xDiv[0] was zero or not.
+    for (i = xDivs[0] == 0 ? 1 : 0; i <= numXDivs && left < W; i++) {
+      if (i == numXDivs) {
+        right = W;
+      } else {
+        right = xDivs[i];
+      }
+      c = getColor(image->rows.data(), left, top, right - 1, bottom - 1);
+      image->colors[colorIndex++] = c;
+      if (kDebug) {
+        if (c != Res_png_9patch::NO_COLOR) {
+          hasColor = true;
+        }
+      }
+      left = right;
+    }
+    top = bottom;
+  }
+
+  assert(colorIndex == numColors);
+
+  if (kDebug && hasColor) {
+    for (i = 0; i < numColors; i++) {
+      if (i == 0) printf("Colors:\n");
+      printf(" #%08x", image->colors[i]);
+      if (i == numColors - 1) printf("\n");
+    }
+  }
+getout:
+  if (errorMsg) {
+    std::stringstream err;
+    err << "9-patch malformed: " << errorMsg;
+    if (errorEdge) {
+      err << "." << std::endl;
+      if (errorPixel >= 0) {
+        err << "Found at pixel #" << errorPixel << " along " << errorEdge << " edge";
+      } else {
+        err << "Found along " << errorEdge << " edge";
+      }
+    }
+    *outError = err.str();
+    return false;
+  }
+  return true;
+}
+
+bool Png::process(const Source& source, std::istream* input, BigBuffer* outBuffer,
+                  const PngOptions& options) {
+  png_byte signature[kPngSignatureSize];
+
+  // Read the PNG signature first.
+  if (!input->read(reinterpret_cast<char*>(signature), kPngSignatureSize)) {
+    mDiag->Error(DiagMessage() << strerror(errno));
+    return false;
+  }
+
+  // If the PNG signature doesn't match, bail early.
+  if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
+    mDiag->Error(DiagMessage() << "not a valid png file");
+    return false;
+  }
+
+  bool result = false;
+  png_structp readPtr = nullptr;
+  png_infop infoPtr = nullptr;
+  png_structp writePtr = nullptr;
+  png_infop writeInfoPtr = nullptr;
+  PngInfo pngInfo = {};
+
+  readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
+  if (!readPtr) {
+    mDiag->Error(DiagMessage() << "failed to allocate read ptr");
+    goto bail;
+  }
+
+  infoPtr = png_create_info_struct(readPtr);
+  if (!infoPtr) {
+    mDiag->Error(DiagMessage() << "failed to allocate info ptr");
+    goto bail;
+  }
+
+  png_set_error_fn(readPtr, reinterpret_cast<png_voidp>(mDiag), nullptr, logWarning);
+
+  // Set the read function to read from std::istream.
+  png_set_read_fn(readPtr, (png_voidp)input, readDataFromStream);
+
+  if (!readPng(mDiag, readPtr, infoPtr, &pngInfo)) {
+    goto bail;
+  }
+
+  if (android::base::EndsWith(source.path, ".9.png")) {
+    std::string errorMsg;
+    if (!do9Patch(&pngInfo, &errorMsg)) {
+      mDiag->Error(DiagMessage() << errorMsg);
+      goto bail;
+    }
+  }
+
+  writePtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
+  if (!writePtr) {
+    mDiag->Error(DiagMessage() << "failed to allocate write ptr");
+    goto bail;
+  }
+
+  writeInfoPtr = png_create_info_struct(writePtr);
+  if (!writeInfoPtr) {
+    mDiag->Error(DiagMessage() << "failed to allocate write info ptr");
+    goto bail;
+  }
+
+  png_set_error_fn(writePtr, nullptr, nullptr, logWarning);
+
+  // Set the write function to write to std::ostream.
+  png_set_write_fn(writePtr, (png_voidp)outBuffer, writeDataToStream, flushDataToStream);
+
+  if (!writePng(mDiag, writePtr, writeInfoPtr, &pngInfo, options.grayscale_tolerance)) {
+    goto bail;
+  }
+
+  result = true;
+bail:
+  if (readPtr) {
+    png_destroy_read_struct(&readPtr, &infoPtr, nullptr);
+  }
+
+  if (writePtr) {
+    png_destroy_write_struct(&writePtr, &writeInfoPtr);
+  }
+  return result;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/PngChunkFilter.cpp b/libs/androidfw/PngChunkFilter.cpp
new file mode 100644
index 0000000..331b948
--- /dev/null
+++ b/libs/androidfw/PngChunkFilter.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 "android-base/stringprintf.h"
+#include "android-base/strings.h"
+#include "androidfw/Png.h"
+#include "androidfw/Streams.h"
+#include "androidfw/StringPiece.h"
+
+using ::android::base::StringPrintf;
+
+namespace android {
+
+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);
+}
+
+// Allow list 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 IsPngChunkAllowed(uint32_t type) {
+  switch (type) {
+    case kPngChunkIHDR:
+    case kPngChunkIDAT:
+    case kPngChunkIEND:
+    case kPngChunkPLTE:
+    case kPngChunktRNS:
+    case kPngChunksRGB:
+      return true;
+    default:
+      return false;
+  }
+}
+
+PngChunkFilter::PngChunkFilter(StringPiece data) : data_(data) {
+  if (android::base::StartsWith(data_, kPngSignature)) {
+    window_start_ = 0;
+    window_end_ = kPngSignatureSize;
+  } else {
+    error_msg_ = "file does not start with PNG signature";
+  }
+}
+
+bool PngChunkFilter::ConsumeWindow(const void** buffer, size_t* len) {
+  if (window_start_ != window_end_) {
+    // We have bytes to give from our window.
+    const size_t bytes_read = window_end_ - window_start_;
+    *buffer = data_.data() + window_start_;
+    *len = bytes_read;
+    window_start_ = window_end_;
+    return true;
+  }
+  return false;
+}
+
+bool PngChunkFilter::Next(const void** buffer, size_t* len) {
+  if (HadError()) {
+    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 (window_end_ < data_.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 (data_.size() - window_end_ < kMinChunkHeaderSize) {
+      error_msg_ = StringPrintf("Not enough space for a PNG chunk @ byte %zu/%zu", window_end_,
+                                data_.size());
+      return false;
+    }
+
+    // Verify the chunk length.
+    const uint32_t chunk_len = Peek32LE(data_.data() + window_end_);
+    if ((size_t)chunk_len > data_.size() - window_end_ - kMinChunkHeaderSize) {
+      // Overflow.
+      const uint32_t chunk_type = Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
+      error_msg_ = StringPrintf(
+          "PNG chunk type %08x is too large: chunk length is %zu but chunk "
+          "starts at byte %zu/%zu",
+          chunk_type, (size_t)chunk_len, window_end_ + kMinChunkHeaderSize, data_.size());
+      return false;
+    }
+
+    // Do we strip this chunk?
+    const uint32_t chunk_type = Peek32LE(data_.data() + window_end_ + sizeof(uint32_t));
+    if (IsPngChunkAllowed(chunk_type)) {
+      // Advance the window to include this chunk.
+      window_end_ += kMinChunkHeaderSize + chunk_len;
+
+      // Special case the IEND chunk, which MUST appear last and libpng stops parsing once it hits
+      // such a chunk (let's do the same).
+      if (chunk_type == kPngChunkIEND) {
+        // Truncate the data to the end of this chunk. There may be garbage trailing after
+        // (b/38169876)
+        data_ = data_.substr(0, window_end_);
+        break;
+      }
+
+    } else {
+      // We want to strip this chunk. If we accumulated a window,
+      // we must return the window now.
+      if (window_start_ != window_end_) {
+        break;
+      }
+
+      // The window is empty, so we can advance past this chunk
+      // and keep looking for the next good chunk,
+      window_end_ += kMinChunkHeaderSize + chunk_len;
+      window_start_ = window_end_;
+    }
+  }
+
+  if (ConsumeWindow(buffer, len)) {
+    return true;
+  }
+  return false;
+}
+
+void PngChunkFilter::BackUp(size_t count) {
+  if (HadError()) {
+    return;
+  }
+  window_start_ -= count;
+}
+
+bool PngChunkFilter::Rewind() {
+  if (HadError()) {
+    return false;
+  }
+  window_start_ = 0;
+  window_end_ = kPngSignatureSize;
+  return true;
+}
+}  // namespace android
diff --git a/libs/androidfw/PngCrunch.cpp b/libs/androidfw/PngCrunch.cpp
new file mode 100644
index 0000000..cf3c0ee
--- /dev/null
+++ b/libs/androidfw/PngCrunch.cpp
@@ -0,0 +1,730 @@
+/*
+ * 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 <png.h>
+#include <zlib.h>
+
+#include <algorithm>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "android-base/errors.h"
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "androidfw/Png.h"
+
+namespace android {
+
+// Custom deleter that destroys libpng read and info structs.
+class PngReadStructDeleter {
+ public:
+  PngReadStructDeleter(png_structp read_ptr, png_infop info_ptr)
+      : read_ptr_(read_ptr), info_ptr_(info_ptr) {
+  }
+
+  ~PngReadStructDeleter() {
+    png_destroy_read_struct(&read_ptr_, &info_ptr_, nullptr);
+  }
+
+ private:
+  png_structp read_ptr_;
+  png_infop info_ptr_;
+
+  DISALLOW_COPY_AND_ASSIGN(PngReadStructDeleter);
+};
+
+// Custom deleter that destroys libpng write and info structs.
+class PngWriteStructDeleter {
+ public:
+  PngWriteStructDeleter(png_structp write_ptr, png_infop info_ptr)
+      : write_ptr_(write_ptr), info_ptr_(info_ptr) {
+  }
+
+  ~PngWriteStructDeleter() {
+    png_destroy_write_struct(&write_ptr_, &info_ptr_);
+  }
+
+ private:
+  png_structp write_ptr_;
+  png_infop info_ptr_;
+
+  DISALLOW_COPY_AND_ASSIGN(PngWriteStructDeleter);
+};
+
+// Custom warning logging method that uses IDiagnostics.
+static void LogWarning(png_structp png_ptr, png_const_charp warning_msg) {
+  android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
+  diag->Warn(android::DiagMessage() << warning_msg);
+}
+
+// Custom error logging method that uses IDiagnostics.
+static void LogError(png_structp png_ptr, png_const_charp error_msg) {
+  android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
+  diag->Error(android::DiagMessage() << error_msg);
+
+  // Causes libpng to longjmp to the spot where setjmp was set. This is how libpng does
+  // error handling. If this custom error handler method were to return, libpng would, by
+  // default, print the error message to stdout and call the same png_longjmp method.
+  png_longjmp(png_ptr, 1);
+}
+
+static void ReadDataFromStream(png_structp png_ptr, png_bytep buffer, png_size_t len) {
+  InputStream* in = (InputStream*)png_get_io_ptr(png_ptr);
+
+  const void* in_buffer;
+  size_t in_len;
+  if (!in->Next(&in_buffer, &in_len)) {
+    if (in->HadError()) {
+      std::stringstream error_msg_builder;
+      error_msg_builder << "failed reading from input";
+      if (!in->GetError().empty()) {
+        error_msg_builder << ": " << in->GetError();
+      }
+      std::string err = error_msg_builder.str();
+      png_error(png_ptr, err.c_str());
+    }
+    return;
+  }
+
+  const size_t bytes_read = std::min(in_len, len);
+  memcpy(buffer, in_buffer, bytes_read);
+  if (bytes_read != in_len) {
+    in->BackUp(in_len - bytes_read);
+  }
+}
+
+static void WriteDataToStream(png_structp png_ptr, png_bytep buffer, png_size_t len) {
+  OutputStream* out = (OutputStream*)png_get_io_ptr(png_ptr);
+
+  void* out_buffer;
+  size_t out_len;
+  while (len > 0) {
+    if (!out->Next(&out_buffer, &out_len)) {
+      if (out->HadError()) {
+        std::stringstream err_msg_builder;
+        err_msg_builder << "failed writing to output";
+        if (!out->GetError().empty()) {
+          err_msg_builder << ": " << out->GetError();
+        }
+        std::string err = out->GetError();
+        png_error(png_ptr, err.c_str());
+      }
+      return;
+    }
+
+    const size_t bytes_written = std::min(out_len, len);
+    memcpy(out_buffer, buffer, bytes_written);
+
+    // Advance the input buffer.
+    buffer += bytes_written;
+    len -= bytes_written;
+
+    // Advance the output buffer.
+    out_len -= bytes_written;
+  }
+
+  // If the entire output buffer wasn't used, backup.
+  if (out_len > 0) {
+    out->BackUp(out_len);
+  }
+}
+
+std::unique_ptr<Image> ReadPng(InputStream* in, IDiagnostics* diag) {
+  // Read the first 8 bytes of the file looking for the PNG signature.
+  // Bail early if it does not match.
+  const png_byte* signature;
+  size_t buffer_size;
+  if (!in->Next((const void**)&signature, &buffer_size)) {
+    if (in->HadError()) {
+      diag->Error(android::DiagMessage() << "failed to read PNG signature: " << in->GetError());
+    } else {
+      diag->Error(android::DiagMessage() << "not enough data for PNG signature");
+    }
+    return {};
+  }
+
+  if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
+    diag->Error(android::DiagMessage() << "file signature does not match PNG signature");
+    return {};
+  }
+
+  // Start at the beginning of the first chunk.
+  in->BackUp(buffer_size - 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 read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+  if (read_ptr == nullptr) {
+    diag->Error(android::DiagMessage() << "failed to create libpng read png_struct");
+    return {};
+  }
+
+  // Create and initialize the memory for image header and data.
+  png_infop info_ptr = png_create_info_struct(read_ptr);
+  if (info_ptr == nullptr) {
+    diag->Error(android::DiagMessage() << "failed to create libpng read png_info");
+    png_destroy_read_struct(&read_ptr, nullptr, nullptr);
+    return {};
+  }
+
+  // Automatically release PNG resources at end of scope.
+  PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);
+
+  // 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(read_ptr))) {
+    return {};
+  }
+
+  // Handle warnings ourselves via IDiagnostics.
+  png_set_error_fn(read_ptr, (png_voidp)&diag, LogError, LogWarning);
+
+  // Set up the read functions which read from our custom data sources.
+  png_set_read_fn(read_ptr, (png_voidp)in, ReadDataFromStream);
+
+  // Skip the signature that we already read.
+  png_set_sig_bytes(read_ptr, kPngSignatureSize);
+
+  // Read the chunk headers.
+  png_read_info(read_ptr, info_ptr);
+
+  // Extract image meta-data from the various chunk headers.
+  uint32_t width, height;
+  int bit_depth, color_type, interlace_method, compression_method, filter_method;
+  png_get_IHDR(read_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method,
+               &compression_method, &filter_method);
+
+  // When the image is read, expand it so that it is in RGBA 8888 format
+  // so that image handling is uniform.
+
+  if (color_type == PNG_COLOR_TYPE_PALETTE) {
+    png_set_palette_to_rgb(read_ptr);
+  }
+
+  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
+    png_set_expand_gray_1_2_4_to_8(read_ptr);
+  }
+
+  if (png_get_valid(read_ptr, info_ptr, PNG_INFO_tRNS)) {
+    png_set_tRNS_to_alpha(read_ptr);
+  }
+
+  if (bit_depth == 16) {
+    png_set_strip_16(read_ptr);
+  }
+
+  if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
+    png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);
+  }
+
+  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    png_set_gray_to_rgb(read_ptr);
+  }
+
+  if (interlace_method != PNG_INTERLACE_NONE) {
+    png_set_interlace_handling(read_ptr);
+  }
+
+  // Once all the options for reading have been set, we need to flush
+  // them to libpng.
+  png_read_update_info(read_ptr, info_ptr);
+
+  // 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()) {
+    diag->Error(android::DiagMessage()
+                << "PNG image dimensions are too large: " << width << "x" << height);
+    return {};
+  }
+
+  std::unique_ptr<Image> output_image = std::make_unique<Image>();
+  output_image->width = static_cast<int32_t>(width);
+  output_image->height = static_cast<int32_t>(height);
+
+  const size_t row_bytes = png_get_rowbytes(read_ptr, info_ptr);
+  CHECK(row_bytes == 4 * width);  // RGBA
+
+  // Allocate one large block to hold the image.
+  output_image->data = std::unique_ptr<uint8_t[]>(new uint8_t[height * row_bytes]);
+
+  // Create an array of rows that index into the data block.
+  output_image->rows = std::unique_ptr<uint8_t*[]>(new uint8_t*[height]);
+  for (uint32_t h = 0; h < height; h++) {
+    output_image->rows[h] = output_image->data.get() + (h * row_bytes);
+  }
+
+  // Actually read the image pixels.
+  png_read_image(read_ptr, output_image->rows.get());
+
+  // Finish reading. This will read any other chunks after the image data.
+  png_read_end(read_ptr, info_ptr);
+
+  return output_image;
+}
+
+// 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 convertible_to_grayscale, bool has_nine_patch,
+                         size_t color_palette_size, size_t alpha_palette_size) {
+  const size_t palette_chunk_size = 16 + color_palette_size * 3;
+  const size_t alpha_chunk_size = 16 + alpha_palette_size;
+  const size_t color_alpha_data_chunk_size = 16 + 4 * width * height;
+  const size_t color_data_chunk_size = 16 + 3 * width * height;
+  const size_t grayscale_alpha_data_chunk_size = 16 + 2 * width * height;
+  const size_t palette_data_chunk_size = 16 + width * height;
+
+  if (grayscale) {
+    if (alpha_palette_size == 0) {
+      // This is the smallest the data can be.
+      return PNG_COLOR_TYPE_GRAY;
+    } else if (color_palette_size <= 256 && !has_nine_patch) {
+      // This grayscale has alpha and can fit within a palette.
+      // See if it is worth fitting into a palette.
+      const size_t palette_threshold = palette_chunk_size + alpha_chunk_size +
+                                       palette_data_chunk_size + kPaletteOverheadConstant;
+      if (grayscale_alpha_data_chunk_size > palette_threshold) {
+        return PNG_COLOR_TYPE_PALETTE;
+      }
+    }
+    return PNG_COLOR_TYPE_GRAY_ALPHA;
+  }
+
+  if (color_palette_size <= 256 && !has_nine_patch) {
+    // This image can fit inside a palette. Let's see if it is worth it.
+    size_t total_size_with_palette = palette_data_chunk_size + palette_chunk_size;
+    size_t total_size_without_palette = color_data_chunk_size;
+    if (alpha_palette_size > 0) {
+      total_size_with_palette += alpha_palette_size;
+      total_size_without_palette = color_alpha_data_chunk_size;
+    }
+
+    if (total_size_without_palette > total_size_with_palette + kPaletteOverheadConstant) {
+      return PNG_COLOR_TYPE_PALETTE;
+    }
+  }
+
+  if (convertible_to_grayscale) {
+    if (alpha_palette_size == 0) {
+      return PNG_COLOR_TYPE_GRAY;
+    } else {
+      return PNG_COLOR_TYPE_GRAY_ALPHA;
+    }
+  }
+
+  if (alpha_palette_size == 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 write_ptr, png_infop write_info_ptr,
+                         std::unordered_map<uint32_t, int>* color_palette,
+                         std::unordered_set<uint32_t>* alpha_palette) {
+  CHECK(color_palette->size() <= 256);
+  CHECK(alpha_palette->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 : *alpha_palette) {
+    (*color_palette)[color] = index++;
+  }
+
+  // Assign the rest of the entries.
+  for (auto& entry : *color_palette) {
+    if (entry.second == -1) {
+      entry.second = index++;
+    }
+  }
+
+  // Create the PNG color palette struct.
+  auto color_palette_bytes = std::unique_ptr<png_color[]>(new png_color[color_palette->size()]);
+
+  std::unique_ptr<png_byte[]> alpha_palette_bytes;
+  if (!alpha_palette->empty()) {
+    alpha_palette_bytes = std::unique_ptr<png_byte[]>(new png_byte[alpha_palette->size()]);
+  }
+
+  for (const auto& entry : *color_palette) {
+    const uint32_t color = entry.first;
+    const int index = entry.second;
+    CHECK(index >= 0);
+    CHECK(static_cast<size_t>(index) < color_palette->size());
+
+    png_colorp slot = color_palette_bytes.get() + index;
+    slot->red = color >> 24;
+    slot->green = color >> 16;
+    slot->blue = color >> 8;
+
+    const png_byte alpha = color & 0x000000ff;
+    if (alpha != 0xff && alpha_palette_bytes) {
+      CHECK(static_cast<size_t>(index) < alpha_palette->size());
+      alpha_palette_bytes[index] = alpha;
+    }
+  }
+
+  // The bytes get copied here, so it is safe to release color_palette_bytes at
+  // the end of function
+  // scope.
+  png_set_PLTE(write_ptr, write_info_ptr, color_palette_bytes.get(), color_palette->size());
+
+  if (alpha_palette_bytes) {
+    png_set_tRNS(write_ptr, write_info_ptr, alpha_palette_bytes.get(), alpha_palette->size(),
+                 nullptr);
+  }
+}
+
+// Write the 9-patch custom PNG chunks to write_info_ptr. This must be done
+// before writing image data.
+static void WriteNinePatch(png_structp write_ptr, png_infop write_info_ptr,
+                           const NinePatch* nine_patch) {
+  // The order of the chunks is important.
+  // 9-patch code in older platforms expects the 9-patch chunk to be last.
+
+  png_unknown_chunk unknown_chunks[3];
+  memset(unknown_chunks, 0, sizeof(unknown_chunks));
+
+  size_t index = 0;
+  size_t chunk_len = 0;
+
+  std::unique_ptr<uint8_t[]> serialized_outline =
+      nine_patch->SerializeRoundedRectOutline(&chunk_len);
+  strcpy((char*)unknown_chunks[index].name, "npOl");
+  unknown_chunks[index].size = chunk_len;
+  unknown_chunks[index].data = (png_bytep)serialized_outline.get();
+  unknown_chunks[index].location = PNG_HAVE_PLTE;
+  index++;
+
+  std::unique_ptr<uint8_t[]> serialized_layout_bounds;
+  if (nine_patch->layout_bounds.nonZero()) {
+    serialized_layout_bounds = nine_patch->SerializeLayoutBounds(&chunk_len);
+    strcpy((char*)unknown_chunks[index].name, "npLb");
+    unknown_chunks[index].size = chunk_len;
+    unknown_chunks[index].data = (png_bytep)serialized_layout_bounds.get();
+    unknown_chunks[index].location = PNG_HAVE_PLTE;
+    index++;
+  }
+
+  std::unique_ptr<uint8_t[]> serialized_nine_patch = nine_patch->SerializeBase(&chunk_len);
+  strcpy((char*)unknown_chunks[index].name, "npTc");
+  unknown_chunks[index].size = chunk_len;
+  unknown_chunks[index].data = (png_bytep)serialized_nine_patch.get();
+  unknown_chunks[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(write_ptr, 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(write_ptr, write_info_ptr, unknown_chunks, index);
+}
+
+bool WritePng(const Image* image, const NinePatch* nine_patch, OutputStream* out,
+              const PngOptions& options, IDiagnostics* diag, bool verbose) {
+  // 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 write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+  if (write_ptr == nullptr) {
+    diag->Error(android::DiagMessage() << "failed to create libpng write png_struct");
+    return false;
+  }
+
+  // Allocate memory to store image header data.
+  png_infop write_info_ptr = png_create_info_struct(write_ptr);
+  if (write_info_ptr == nullptr) {
+    diag->Error(android::DiagMessage() << "failed to create libpng write png_info");
+    png_destroy_write_struct(&write_ptr, nullptr);
+    return false;
+  }
+
+  // Automatically release PNG resources at end of scope.
+  PngWriteStructDeleter png_write_deleter(write_ptr, write_info_ptr);
+
+  // 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(write_ptr))) {
+    return false;
+  }
+
+  // Handle warnings with our IDiagnostics.
+  png_set_error_fn(write_ptr, (png_voidp)&diag, LogError, LogWarning);
+
+  // Set up the write functions which write to our custom data sources.
+  png_set_write_fn(write_ptr, (png_voidp)out, WriteDataToStream, nullptr);
+
+  // We want small files and can take the performance hit to achieve this goal.
+  png_set_compression_level(write_ptr, 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> color_palette;
+  std::unordered_set<uint32_t> alpha_palette;
+  bool needs_to_zero_rgb_channels_of_transparent_pixels = false;
+  bool grayscale = true;
+  int max_gray_deviation = 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.
+        needs_to_zero_rgb_channels_of_transparent_pixels =
+            needs_to_zero_rgb_channels_of_transparent_pixels ||
+            (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;
+      color_palette[color] = -1;
+
+      // If the pixel has non-opaque alpha, insert it into the
+      // alpha palette.
+      if (alpha != 0xff) {
+        alpha_palette.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.
+      max_gray_deviation = std::max(std::abs(red - green), max_gray_deviation);
+      max_gray_deviation = std::max(std::abs(green - blue), max_gray_deviation);
+      max_gray_deviation = std::max(std::abs(blue - red), max_gray_deviation);
+    }
+  }
+
+  if (verbose) {
+    android::DiagMessage msg;
+    msg << " paletteSize=" << color_palette.size() << " alphaPaletteSize=" << alpha_palette.size()
+        << " maxGrayDeviation=" << max_gray_deviation
+        << " grayScale=" << (grayscale ? "true" : "false");
+    diag->Note(msg);
+  }
+
+  const bool convertible_to_grayscale = max_gray_deviation <= options.grayscale_tolerance;
+
+  const int new_color_type =
+      PickColorType(image->width, image->height, grayscale, convertible_to_grayscale,
+                    nine_patch != nullptr, color_palette.size(), alpha_palette.size());
+
+  if (verbose) {
+    android::DiagMessage msg;
+    msg << "encoding PNG ";
+    if (nine_patch) {
+      msg << "(with 9-patch) as ";
+    }
+    switch (new_color_type) {
+      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 " << new_color_type;
+        break;
+    }
+    diag->Note(msg);
+  }
+
+  png_set_IHDR(write_ptr, write_info_ptr, image->width, image->height, 8, new_color_type,
+               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+  if (new_color_type & PNG_COLOR_MASK_PALETTE) {
+    // Assigns indices to the palette, and writes the encoded palette to the
+    // libpng writePtr.
+    WritePalette(write_ptr, write_info_ptr, &color_palette, &alpha_palette);
+    png_set_filter(write_ptr, 0, PNG_NO_FILTERS);
+  } else {
+    png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);
+  }
+
+  if (nine_patch) {
+    WriteNinePatch(write_ptr, write_info_ptr, nine_patch);
+  }
+
+  // Flush our updates to the header.
+  png_write_info(write_ptr, write_info_ptr);
+
+  // Write out each row of image data according to its encoding.
+  if (new_color_type == PNG_COLOR_TYPE_PALETTE) {
+    // 1 byte/pixel.
+    auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width]);
+
+    for (int32_t y = 0; y < image->height; y++) {
+      png_const_bytep in_row = image->rows[y];
+      for (int32_t x = 0; x < image->width; x++) {
+        int rr = *in_row++;
+        int gg = *in_row++;
+        int bb = *in_row++;
+        int aa = *in_row++;
+        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 = color_palette[color];
+        CHECK(idx != -1);
+        out_row[x] = static_cast<png_byte>(idx);
+      }
+      png_write_row(write_ptr, out_row.get());
+    }
+  } else if (new_color_type == PNG_COLOR_TYPE_GRAY || new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+    const size_t bpp = new_color_type == PNG_COLOR_TYPE_GRAY ? 1 : 2;
+    auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
+
+    for (int32_t y = 0; y < image->height; y++) {
+      png_const_bytep in_row = image->rows[y];
+      for (int32_t x = 0; x < image->width; x++) {
+        int rr = in_row[x * 4];
+        int gg = in_row[x * 4 + 1];
+        int bb = in_row[x * 4 + 2];
+        int aa = in_row[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.
+          out_row[x * bpp] = in_row[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
+          out_row[x * bpp] = (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
+        }
+
+        if (bpp == 2) {
+          // Write out alpha if we have it.
+          out_row[x * bpp + 1] = aa;
+        }
+      }
+      png_write_row(write_ptr, out_row.get());
+    }
+  } else if (new_color_type == PNG_COLOR_TYPE_RGB || new_color_type == PNG_COLOR_TYPE_RGBA) {
+    const size_t bpp = new_color_type == PNG_COLOR_TYPE_RGB ? 3 : 4;
+    if (needs_to_zero_rgb_channels_of_transparent_pixels) {
+      // The source RGBA data can't be used as-is, because we need to zero out
+      // the RGB values of transparent pixels.
+      auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);
+
+      for (int32_t y = 0; y < image->height; y++) {
+        png_const_bytep in_row = image->rows[y];
+        for (int32_t x = 0; x < image->width; x++) {
+          int rr = *in_row++;
+          int gg = *in_row++;
+          int bb = *in_row++;
+          int aa = *in_row++;
+          if (aa == 0) {
+            // Zero out the RGB channels when transparent.
+            rr = gg = bb = 0;
+          }
+          out_row[x * bpp] = rr;
+          out_row[x * bpp + 1] = gg;
+          out_row[x * bpp + 2] = bb;
+          if (bpp == 4) {
+            out_row[x * bpp + 3] = aa;
+          }
+        }
+        png_write_row(write_ptr, out_row.get());
+      }
+    } else {
+      // The source image can be used as-is, just tell libpng whether or not to
+      // ignore the alpha channel.
+      if (new_color_type == PNG_COLOR_TYPE_RGB) {
+        // Delete the extraneous alpha values that we appended to our buffer
+        // when reading the original values.
+        png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);
+      }
+      png_write_image(write_ptr, image->rows.get());
+    }
+  } else {
+    LOG(FATAL) << "unreachable";
+  }
+
+  png_write_end(write_ptr, write_info_ptr);
+  return true;
+}
+
+}  // namespace android
diff --git a/libs/androidfw/include/androidfw/BigBufferStream.h b/libs/androidfw/include/androidfw/BigBufferStream.h
new file mode 100644
index 0000000..e55fe0d
--- /dev/null
+++ b/libs/androidfw/include/androidfw/BigBufferStream.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "BigBuffer.h"
+#include "Streams.h"
+
+namespace android {
+
+class BigBufferInputStream : public KnownSizeInputStream {
+ public:
+  inline explicit BigBufferInputStream(const BigBuffer* buffer)
+      : buffer_(buffer), iter_(buffer->begin()) {
+  }
+  virtual ~BigBufferInputStream() = default;
+
+  bool Next(const void** data, size_t* size) override;
+
+  void BackUp(size_t count) override;
+
+  bool CanRewind() const override;
+
+  bool Rewind() override;
+
+  size_t ByteCount() const override;
+
+  bool HadError() const override;
+
+  size_t TotalSize() const override;
+
+  bool ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BigBufferInputStream);
+
+  const BigBuffer* buffer_;
+  BigBuffer::const_iterator iter_;
+  size_t offset_ = 0;
+  size_t bytes_read_ = 0;
+};
+
+class BigBufferOutputStream : public OutputStream {
+ public:
+  inline explicit BigBufferOutputStream(BigBuffer* buffer) : buffer_(buffer) {
+  }
+  virtual ~BigBufferOutputStream() = default;
+
+  bool Next(void** data, size_t* size) override;
+
+  void BackUp(size_t count) override;
+
+  size_t ByteCount() const override;
+
+  bool HadError() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream);
+
+  BigBuffer* buffer_;
+};
+
+}  // namespace android
\ No newline at end of file
diff --git a/libs/androidfw/include/androidfw/FileStream.h b/libs/androidfw/include/androidfw/FileStream.h
new file mode 100644
index 0000000..fb84a91
--- /dev/null
+++ b/libs/androidfw/include/androidfw/FileStream.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "Streams.h"
+#include "android-base/macros.h"
+#include "android-base/unique_fd.h"
+
+namespace android {
+
+constexpr size_t kDefaultBufferCapacity = 4096u;
+
+class FileInputStream : public InputStream {
+ public:
+  explicit FileInputStream(const std::string& path,
+                           size_t buffer_capacity = kDefaultBufferCapacity);
+
+  // Take ownership of `fd`.
+  explicit FileInputStream(int fd, size_t buffer_capacity = kDefaultBufferCapacity);
+
+  bool Next(const void** data, size_t* size) override;
+
+  void BackUp(size_t count) override;
+
+  size_t ByteCount() const override;
+
+  bool HadError() const override;
+
+  std::string GetError() const override;
+
+  bool ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FileInputStream);
+
+  android::base::unique_fd fd_;
+  std::string error_;
+  std::unique_ptr<uint8_t[]> buffer_;
+  size_t buffer_capacity_ = 0u;
+  size_t buffer_offset_ = 0u;
+  size_t buffer_size_ = 0u;
+  size_t total_byte_count_ = 0u;
+};
+
+class FileOutputStream : public OutputStream {
+ public:
+  explicit FileOutputStream(const std::string& path,
+                            size_t buffer_capacity = kDefaultBufferCapacity);
+
+  // Does not take ownership of `fd`.
+  explicit FileOutputStream(int fd, size_t buffer_capacity = kDefaultBufferCapacity);
+
+  // Takes ownership of `fd`.
+  explicit FileOutputStream(android::base::unique_fd fd,
+                            size_t buffer_capacity = kDefaultBufferCapacity);
+
+  ~FileOutputStream();
+
+  bool Next(void** data, size_t* size) override;
+
+  // Immediately flushes out the contents of the buffer to disk.
+  bool Flush();
+
+  void BackUp(size_t count) override;
+
+  size_t ByteCount() const override;
+
+  bool HadError() const override;
+
+  std::string GetError() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FileOutputStream);
+
+  bool FlushImpl();
+
+  android::base::unique_fd owned_fd_;
+  int fd_;
+  std::string error_;
+  std::unique_ptr<uint8_t[]> buffer_;
+  size_t buffer_capacity_ = 0u;
+  size_t buffer_offset_ = 0u;
+  size_t total_byte_count_ = 0u;
+};
+
+}  // namespace android
\ No newline at end of file
diff --git a/libs/androidfw/include/androidfw/Image.h b/libs/androidfw/include/androidfw/Image.h
new file mode 100644
index 0000000..c18c34c
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Image.h
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "android-base/macros.h"
+
+namespace android {
+
+/**
+ * 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* err_out);
+
+  /**
+   * 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 layout_bounds;
+
+  /**
+   * 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 outline_radius = 0.0f;
+
+  /**
+   * The largest alpha value within the outline.
+   */
+  uint32_t outline_alpha = 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> horizontal_stretch_regions;
+
+  /**
+   * 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> vertical_stretch_regions;
+
+  /**
+   * 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> region_colors;
+
+  /**
+   * 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* out_len) const;
+
+  /**
+   * Serializes the layout bounds.
+   */
+  std::unique_ptr<uint8_t[]> SerializeLayoutBounds(size_t* out_len) const;
+
+  /**
+   * Serializes the rounded-rect outline.
+   */
+  std::unique_ptr<uint8_t[]> SerializeRoundedRectOutline(size_t* out_len) 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& nine_patch);
+
+}  // namespace android
\ No newline at end of file
diff --git a/libs/androidfw/include/androidfw/Png.h b/libs/androidfw/include/androidfw/Png.h
new file mode 100644
index 0000000..2ece43e
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Png.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "BigBuffer.h"
+#include "IDiagnostics.h"
+#include "Image.h"
+#include "Source.h"
+#include "Streams.h"
+#include "android-base/macros.h"
+
+namespace android {
+// Size in bytes of the PNG signature.
+constexpr size_t kPngSignatureSize = 8u;
+
+struct PngOptions {
+  int grayscale_tolerance = 0;
+};
+
+/**
+ * Deprecated. Removing once new PNG crunching code is proved to be correct.
+ */
+class Png {
+ public:
+  explicit Png(IDiagnostics* diag) : mDiag(diag) {
+  }
+
+  bool process(const Source& source, std::istream* input, BigBuffer* outBuffer,
+               const PngOptions& options);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Png);
+
+  IDiagnostics* mDiag;
+};
+
+/**
+ * An InputStream that filters out unimportant PNG chunks.
+ */
+class PngChunkFilter : public InputStream {
+ public:
+  explicit PngChunkFilter(StringPiece data);
+  virtual ~PngChunkFilter() = default;
+
+  bool Next(const void** buffer, size_t* len) override;
+  void BackUp(size_t count) override;
+
+  bool CanRewind() const override {
+    return true;
+  }
+  bool Rewind() override;
+  size_t ByteCount() const override {
+    return window_start_;
+  }
+
+  bool HadError() const override {
+    return !error_msg_.empty();
+  }
+  std::string GetError() const override {
+    return error_msg_;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PngChunkFilter);
+
+  bool ConsumeWindow(const void** buffer, size_t* len);
+
+  StringPiece data_;
+  size_t window_start_ = 0;
+  size_t window_end_ = 0;
+  std::string error_msg_;
+};
+/**
+ * Reads a PNG from the InputStream into memory as an RGBA Image.
+ */
+std::unique_ptr<Image> ReadPng(InputStream* in, IDiagnostics* diag);
+
+/**
+ * Writes the RGBA Image, with optional 9-patch meta-data, into the OutputStream
+ * as a PNG.
+ */
+bool WritePng(const Image* image, const NinePatch* nine_patch, OutputStream* out,
+              const PngOptions& options, IDiagnostics* diag, bool verbose);
+}  // namespace android
\ No newline at end of file
diff --git a/libs/androidfw/include/androidfw/Streams.h b/libs/androidfw/include/androidfw/Streams.h
new file mode 100644
index 0000000..2daf0e2
--- /dev/null
+++ b/libs/androidfw/include/androidfw/Streams.h
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+#include "android-base/off64_t.h"
+
+namespace android {
+
+// InputStream interface that mimics protobuf's ZeroCopyInputStream,
+// with added error handling methods to better report issues.
+class InputStream {
+ public:
+  virtual ~InputStream() = default;
+
+  // Returns a chunk of data for reading. data and size must not be nullptr.
+  // Returns true so long as there is more data to read, returns false if an error occurred
+  // or no data remains. If an error occurred, check HadError().
+  // The stream owns the buffer returned from this method and the buffer is invalidated
+  // anytime another mutable method is called.
+  virtual bool Next(const void** data, size_t* size) = 0;
+
+  // Backup count bytes, where count is smaller or equal to the size of the last buffer returned
+  // from Next().
+  // Useful when the last block returned from Next() wasn't fully read.
+  virtual void BackUp(size_t count) = 0;
+
+  // Returns true if this InputStream can rewind. If so, Rewind() can be called.
+  virtual bool CanRewind() const {
+    return false;
+  };
+
+  // Rewinds the stream to the beginning so it can be read again.
+  // Returns true if the rewind succeeded.
+  // This does nothing if CanRewind() returns false.
+  virtual bool Rewind() {
+    return false;
+  }
+
+  // Returns the number of bytes that have been read from the stream.
+  virtual size_t ByteCount() const = 0;
+
+  // Returns an error message if HadError() returned true.
+  virtual std::string GetError() const {
+    return {};
+  }
+
+  // Returns true if an error occurred. Errors are permanent.
+  virtual bool HadError() const = 0;
+
+  virtual bool ReadFullyAtOffset(void* data, size_t byte_count, off64_t offset) {
+    (void)data;
+    (void)byte_count;
+    (void)offset;
+    return false;
+  }
+};
+
+// A sub-InputStream interface that knows the total size of its stream.
+class KnownSizeInputStream : public InputStream {
+ public:
+  virtual size_t TotalSize() const = 0;
+};
+
+// OutputStream interface that mimics protobuf's ZeroCopyOutputStream,
+// with added error handling methods to better report issues.
+class OutputStream {
+ public:
+  virtual ~OutputStream() = default;
+
+  // Returns a buffer to which data can be written to. The data written to this buffer will
+  // eventually be written to the stream. Call BackUp() if the data written doesn't occupy the
+  // entire buffer.
+  // Return false if there was an error.
+  // The stream owns the buffer returned from this method and the buffer is invalidated
+  // anytime another mutable method is called.
+  virtual bool Next(void** data, size_t* size) = 0;
+
+  // Backup count bytes, where count is smaller or equal to the size of the last buffer returned
+  // from Next().
+  // Useful for when the last block returned from Next() wasn't fully written to.
+  virtual void BackUp(size_t count) = 0;
+
+  // Returns the number of bytes that have been written to the stream.
+  virtual size_t ByteCount() const = 0;
+
+  // Returns an error message if HadError() returned true.
+  virtual std::string GetError() const {
+    return {};
+  }
+
+  // Returns true if an error occurred. Errors are permanent.
+  virtual bool HadError() const = 0;
+};
+
+}  // namespace android
\ No newline at end of file
diff --git a/libs/androidfw/tests/FileStream_test.cpp b/libs/androidfw/tests/FileStream_test.cpp
new file mode 100644
index 0000000..9785975
--- /dev/null
+++ b/libs/androidfw/tests/FileStream_test.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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 "androidfw/FileStream.h"
+#include "androidfw/StringPiece.h"
+
+#include "android-base/file.h"
+#include "android-base/macros.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::android::StringPiece;
+using ::testing::Eq;
+using ::testing::NotNull;
+using ::testing::StrEq;
+
+namespace android {
+
+TEST(FileInputStreamTest, NextAndBackup) {
+  std::string input = "this is a cool string";
+  TemporaryFile file;
+  ASSERT_THAT(TEMP_FAILURE_RETRY(write(file.fd, input.c_str(), input.size())), Eq(21));
+  lseek64(file.fd, 0, SEEK_SET);
+
+  // Use a small buffer size so that we can call Next() a few times.
+  FileInputStream in(file.release(), 10u);
+  ASSERT_FALSE(in.HadError());
+  EXPECT_THAT(in.ByteCount(), Eq(0u));
+
+  const void* buffer;
+  size_t size;
+  ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError();
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  EXPECT_THAT(in.ByteCount(), Eq(10u));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a "));
+
+  ASSERT_TRUE(in.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  EXPECT_THAT(in.ByteCount(), Eq(20u));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
+
+  in.BackUp(5u);
+  EXPECT_THAT(in.ByteCount(), Eq(15u));
+
+  ASSERT_TRUE(in.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(5u));
+  ASSERT_THAT(buffer, NotNull());
+  ASSERT_THAT(in.ByteCount(), Eq(20u));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin"));
+
+  // Backup 1 more than possible. Should clamp.
+  in.BackUp(11u);
+  EXPECT_THAT(in.ByteCount(), Eq(10u));
+
+  ASSERT_TRUE(in.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  ASSERT_THAT(in.ByteCount(), Eq(20u));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
+
+  ASSERT_TRUE(in.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(1u));
+  ASSERT_THAT(buffer, NotNull());
+  ASSERT_THAT(in.ByteCount(), Eq(21u));
+  EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g"));
+
+  EXPECT_FALSE(in.Next(&buffer, &size));
+  EXPECT_FALSE(in.HadError());
+}
+
+TEST(FileOutputStreamTest, NextAndBackup) {
+  const std::string input = "this is a cool string";
+
+  TemporaryFile file;
+
+  FileOutputStream out(file.fd, 10u);
+  ASSERT_FALSE(out.HadError());
+  EXPECT_THAT(out.ByteCount(), Eq(0u));
+
+  void* buffer;
+  size_t size;
+  ASSERT_TRUE(out.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  EXPECT_THAT(out.ByteCount(), Eq(10u));
+  memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size);
+
+  ASSERT_TRUE(out.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  EXPECT_THAT(out.ByteCount(), Eq(20u));
+  memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size);
+
+  ASSERT_TRUE(out.Next(&buffer, &size));
+  ASSERT_THAT(size, Eq(10u));
+  ASSERT_THAT(buffer, NotNull());
+  EXPECT_THAT(out.ByteCount(), Eq(30u));
+  reinterpret_cast<char*>(buffer)[0] = input[20u];
+  out.BackUp(size - 1);
+  EXPECT_THAT(out.ByteCount(), Eq(21u));
+
+  ASSERT_TRUE(out.Flush());
+
+  lseek64(file.fd, 0, SEEK_SET);
+
+  std::string actual;
+  ASSERT_TRUE(android::base::ReadFdToString(file.fd, &actual));
+  EXPECT_THAT(actual, StrEq(input));
+}
+
+}  // namespace android
diff --git a/libs/androidfw/tests/NinePatch_test.cpp b/libs/androidfw/tests/NinePatch_test.cpp
new file mode 100644
index 0000000..7ee8e9e
--- /dev/null
+++ b/libs/androidfw/tests/NinePatch_test.cpp
@@ -0,0 +1,341 @@
+/*
+ * 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 "androidfw/Image.h"
+#include "androidfw/ResourceTypes.h"
+#include "gtest/gtest.h"
+
+namespace android {
+
+// 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,
+};
+
+static uint8_t* kStretchAndPadding5x5[] = {
+    (uint8_t*)WHITE WHITE BLACK WHITE WHITE, (uint8_t*)WHITE RED RED RED WHITE,
+    (uint8_t*)BLACK RED RED RED BLACK,       (uint8_t*)WHITE RED RED RED WHITE,
+    (uint8_t*)WHITE WHITE BLACK 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> nine_patch = NinePatch::Create(kSingleStretch7x6, 7, 6, &err);
+  ASSERT_NE(nullptr, nine_patch);
+
+  ASSERT_EQ(1u, nine_patch->horizontal_stretch_regions.size());
+  ASSERT_EQ(1u, nine_patch->vertical_stretch_regions.size());
+
+  EXPECT_EQ(Range(1, 4), nine_patch->horizontal_stretch_regions.front());
+  EXPECT_EQ(Range(1, 3), nine_patch->vertical_stretch_regions.front());
+}
+
+TEST(NinePatchTest, MultipleStretchRegions) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kMultipleStretch10x7, 10, 7, &err);
+  ASSERT_NE(nullptr, nine_patch);
+
+  ASSERT_EQ(3u, nine_patch->horizontal_stretch_regions.size());
+  ASSERT_EQ(2u, nine_patch->vertical_stretch_regions.size());
+
+  EXPECT_EQ(Range(1, 2), nine_patch->horizontal_stretch_regions[0]);
+  EXPECT_EQ(Range(3, 5), nine_patch->horizontal_stretch_regions[1]);
+  EXPECT_EQ(Range(6, 7), nine_patch->horizontal_stretch_regions[2]);
+
+  EXPECT_EQ(Range(0, 2), nine_patch->vertical_stretch_regions[0]);
+  EXPECT_EQ(Range(3, 5), nine_patch->vertical_stretch_regions[1]);
+}
+
+TEST(NinePatchTest, InferPaddingFromStretchRegions) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kMultipleStretch10x7, 10, 7, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 0, 1, 0), nine_patch->padding);
+}
+
+TEST(NinePatchTest, Padding) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kPadding6x5, 6, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->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> nine_patch = NinePatch::Create(kLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds);
+
+  nine_patch = NinePatch::Create(kAsymmetricLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 0, 0), nine_patch->layout_bounds);
+}
+
+TEST(NinePatchTest, PaddingAndLayoutBounds) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kPaddingAndLayoutBounds5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->padding);
+  EXPECT_EQ(Bounds(1, 1, 1, 1), nine_patch->layout_bounds);
+}
+
+TEST(NinePatchTest, RegionColorsAreCorrect) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kColorfulImage5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+
+  std::vector<uint32_t> expected_colors = {
+      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(expected_colors, nine_patch->region_colors);
+}
+
+TEST(NinePatchTest, OutlineFromOpaqueImage) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kOutlineOpaque10x10, 10, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(2, 2, 2, 2), nine_patch->outline);
+  EXPECT_EQ(0x000000ffu, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
+}
+
+TEST(NinePatchTest, OutlineFromTranslucentImage) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kOutlineTranslucent10x10, 10, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(3, 3, 3, 3), nine_patch->outline);
+  EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
+}
+
+TEST(NinePatchTest, OutlineFromOffCenterImage) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch =
+      NinePatch::Create(kOutlineOffsetTranslucent12x10, 12, 10, &err);
+  ASSERT_NE(nullptr, nine_patch);
+
+  // 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 behavior I'm breaking, I will leave it at the
+  // incorrect:
+  EXPECT_EQ(Bounds(4, 3, 3, 3), nine_patch->outline);
+
+  EXPECT_EQ(0x000000b3u, nine_patch->outline_alpha);
+  EXPECT_EQ(0.0f, nine_patch->outline_radius);
+}
+
+TEST(NinePatchTest, OutlineRadius) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kOutlineRadius5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+  EXPECT_EQ(Bounds(0, 0, 0, 0), nine_patch->outline);
+  EXPECT_EQ(3.4142f, nine_patch->outline_radius);
+}
+
+::testing::AssertionResult BigEndianOne(uint8_t* cursor) {
+  if (cursor[0] == 0 && cursor[1] == 0 && cursor[2] == 0 && cursor[3] == 1) {
+    return ::testing::AssertionSuccess();
+  }
+  return ::testing::AssertionFailure() << "Not BigEndian 1";
+}
+
+TEST(NinePatchTest, SerializePngEndianness) {
+  std::string err;
+  std::unique_ptr<NinePatch> nine_patch = NinePatch::Create(kStretchAndPadding5x5, 5, 5, &err);
+  ASSERT_NE(nullptr, nine_patch);
+
+  size_t len;
+  std::unique_ptr<uint8_t[]> data = nine_patch->SerializeBase(&len);
+  ASSERT_NE(nullptr, data);
+  ASSERT_NE(0u, len);
+
+  // Skip past wasDeserialized + numXDivs + numYDivs + numColors + xDivsOffset +
+  // yDivsOffset
+  // (12 bytes)
+  uint8_t* cursor = data.get() + 12;
+
+  // Check that padding is big-endian. Expecting value 1.
+  EXPECT_TRUE(BigEndianOne(cursor));
+  EXPECT_TRUE(BigEndianOne(cursor + 4));
+  EXPECT_TRUE(BigEndianOne(cursor + 8));
+  EXPECT_TRUE(BigEndianOne(cursor + 12));
+}
+
+}  // namespace android
