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;