AAPT2: Refactor PngCrunching

PngCrunching now has a slightly better heuristic of choosing to encode
an image as a palette or RGB. For small images, RGB compresses much better
than a palette.

The original PNG is used as-is (minus some optional chunks being stripped)
if the resulting crunched PNG is larger than the original.

9-patch handling is abstracted away from PNGs, paving the way
for other 9-patches, like WebP.

TODO: handle PNGs with 9-patch chunks already present, which
should just be passed through. This will allow for 3rd party
tools to generate 9-patches.

TODO: implement cheap transparency: when one color is used to represent
transparent, and all other colors are opaque.

Bug:30053276
Change-Id: I5167f53b91d1efa462d9f03d6b9108d9b541c0c1
diff --git a/tools/aapt2/util/BigBuffer.h b/tools/aapt2/util/BigBuffer.h
index ba8532f..685614f 100644
--- a/tools/aapt2/util/BigBuffer.h
+++ b/tools/aapt2/util/BigBuffer.h
@@ -82,6 +82,20 @@
     T* nextBlock(size_t count = 1);
 
     /**
+     * Returns the next block available and puts the size in outCount.
+     * This is useful for grabbing blocks where the size doesn't matter.
+     * Use backUp() to give back any bytes that were not used.
+     */
+    void* nextBlock(size_t* outCount);
+
+    /**
+     * Backs up count bytes. This must only be called after nextBlock()
+     * and can not be larger than sizeof(T) * count of the last nextBlock()
+     * call.
+     */
+    void backUp(size_t count);
+
+    /**
      * Moves the specified BigBuffer into this one. When this method
      * returns, buffer is empty.
      */
@@ -97,6 +111,8 @@
      */
     void align4();
 
+    size_t getBlockSize() const;
+
     const_iterator begin() const;
     const_iterator end() const;
 
@@ -123,6 +139,10 @@
     return mSize;
 }
 
+inline size_t BigBuffer::getBlockSize() const {
+    return mBlockSize;
+}
+
 template <typename T>
 inline T* BigBuffer::nextBlock(size_t count) {
     static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type");
@@ -130,6 +150,12 @@
     return reinterpret_cast<T*>(nextBlockImpl(sizeof(T) * count));
 }
 
+inline void BigBuffer::backUp(size_t count) {
+    Block& block = mBlocks.back();
+    block.size -= count;
+    mSize -= count;
+}
+
 inline void BigBuffer::appendBuffer(BigBuffer&& buffer) {
     std::move(buffer.mBlocks.begin(), buffer.mBlocks.end(), std::back_inserter(mBlocks));
     mSize += buffer.mSize;