diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkPixelSerializer.cpp | 24 | ||||
-rw-r--r-- | src/core/SkWriteBuffer.cpp | 19 | ||||
-rw-r--r-- | src/image/SkImage.cpp | 22 | ||||
-rw-r--r-- | src/images/SkImageDecoder_ktx.cpp | 36 | ||||
-rw-r--r-- | src/images/SkImageEncoder.cpp | 10 |
5 files changed, 78 insertions, 33 deletions
diff --git a/src/core/SkPixelSerializer.cpp b/src/core/SkPixelSerializer.cpp new file mode 100644 index 0000000000..a694bbe846 --- /dev/null +++ b/src/core/SkPixelSerializer.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkPixelSerializer.h" + +SkData* SkPixelSerializer::reencodeData(SkData* encoded) { + return encoded ? this->onReencodeData(encoded) : nullptr; +} + +SkData* SkPixelSerializer::encodePixels(const SkImageInfo& info, const void* pixels, + size_t rowBytes) { + if (kUnknown_SkColorType == info.colorType() || !pixels) { + return nullptr; + } + return this->onEncodePixels(info, pixels, rowBytes); +} + +SkData* SkPixelSerializer::encodePixels(const SkPixmap& pixmap) { + return this->encodePixels(pixmap.info(), pixmap.addr(), pixmap.rowBytes()); +} diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp index 1dfe0b3972..1799df1714 100644 --- a/src/core/SkWriteBuffer.cpp +++ b/src/core/SkWriteBuffer.cpp @@ -186,13 +186,15 @@ void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) { SkPixelRef* pixelRef = bitmap.pixelRef(); if (pixelRef) { // see if the pixelref already has an encoded version - SkAutoDataUnref existingData(pixelRef->refEncodedData()); - if (existingData.get() != nullptr) { + SkAutoDataUnref encodedData(pixelRef->refEncodedData()); + if (encodedData) { // Assumes that if the client did not set a serializer, they are // happy to get the encoded data. - if (!fPixelSerializer || fPixelSerializer->useEncodedData(existingData->data(), - existingData->size())) { - write_encoded_bitmap(this, existingData, bitmap.pixelRefOrigin()); + if (fPixelSerializer) { + encodedData.reset(fPixelSerializer->reencodeData(encodedData)); + } + if (encodedData) { + write_encoded_bitmap(this, encodedData, bitmap.pixelRefOrigin()); return; } } @@ -200,12 +202,9 @@ void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) { // see if the caller wants to manually encode SkAutoPixmapUnlock result; if (fPixelSerializer && bitmap.requestLock(&result)) { - const SkPixmap& pmap = result.pixmap(); SkASSERT(nullptr == fBitmapHeap); - SkAutoDataUnref data(fPixelSerializer->encodePixels(pmap.info(), - pmap.addr(), - pmap.rowBytes())); - if (data.get() != nullptr) { + SkAutoDataUnref data(fPixelSerializer->encodePixels(result.pixmap())); + if (data) { // if we have to "encode" the bitmap, then we assume there is no // offset to share, since we are effectively creating a new pixelref write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index ee76a7ea39..240c06e63b 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -74,6 +74,14 @@ SkShader* SkImage::newShader(SkShader::TileMode tileX, } SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { + SkAutoDataUnref encoded(this->refEncoded()); + if (encoded) { + SkAutoDataUnref reencoded(SkImageEncoder::ReencodeData(encoded, type)); + if (reencoded) { + return reencoded.detach(); + } + } + SkBitmap bm; if (as_IB(this)->getROPixels(&bm)) { return SkImageEncoder::EncodeData(bm, type, quality); @@ -85,10 +93,6 @@ namespace { class DefaultSerializer : public SkPixelSerializer { protected: - bool onUseEncodedData(const void *data, size_t len) override { - return true; - } - SkData* onEncodePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes) override { return SkImageEncoder::EncodeData(info, pixels, rowBytes, SkImageEncoder::kPNG_Type, 100); } @@ -101,15 +105,17 @@ SkData* SkImage::encode(SkPixelSerializer* serializer) const { SkPixelSerializer* effectiveSerializer = serializer ? serializer : &defaultSerializer; SkAutoTUnref<SkData> encoded(this->refEncoded()); - if (encoded && effectiveSerializer->useEncodedData(encoded->data(), encoded->size())) { - return encoded.detach(); + if (encoded) { + encoded.reset(effectiveSerializer->reencodeData(encoded)); + if (encoded) { + return encoded.detach(); + } } SkBitmap bm; SkAutoPixmapUnlock apu; if (as_IB(this)->getROPixels(&bm) && bm.requestLock(&apu)) { - const SkPixmap& pmap = apu.pixmap(); - return effectiveSerializer->encodePixels(pmap.info(), pmap.addr(), pmap.rowBytes()); + return effectiveSerializer->encodePixels(apu.pixmap()); } return nullptr; diff --git a/src/images/SkImageDecoder_ktx.cpp b/src/images/SkImageDecoder_ktx.cpp index a95ab6f602..f903b3fd56 100644 --- a/src/images/SkImageDecoder_ktx.cpp +++ b/src/images/SkImageDecoder_ktx.cpp @@ -252,34 +252,40 @@ SkImageDecoder::Result SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* b class SkKTXImageEncoder : public SkImageEncoder { protected: bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) override; + SkData* onReencodeData(SkData*) override; private: virtual bool encodePKM(SkWStream* stream, const SkData *data); typedef SkImageEncoder INHERITED; }; +SkData* SkKTXImageEncoder::onReencodeData(SkData* encoded) { + const uint8_t* bytes = encoded->bytes(); + if (etc1_pkm_is_valid(bytes)) { + SkDynamicMemoryWStream stream; + if (this->encodePKM(&stream, encoded)) { + return stream.copyToData(); + } + } + // Is it a KTX file?? + if (SkKTXFile::is_ktx(bytes)) { + return SkRef(encoded); + } + return nullptr; +} + bool SkKTXImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, int) { if (!bitmap.pixelRef()) { return false; } - SkAutoDataUnref data(bitmap.pixelRef()->refEncodedData()); - - // Is this even encoded data? - if (data) { - const uint8_t *bytes = data->bytes(); - if (etc1_pkm_is_valid(bytes)) { - return this->encodePKM(stream, data); - } - // Is it a KTX file?? - if (SkKTXFile::is_ktx(bytes)) { - return stream->write(bytes, data->size()); + SkAutoDataUnref encoded(bitmap.pixelRef()->refEncodedData()); + if (encoded) { + SkAutoDataUnref reencoded(this->onReencodeData(encoded)); + if (reencoded) { + return stream->write(reencoded->bytes(), reencoded->size()); } - - // If it's neither a KTX nor a PKM, then we need to - // get at the actual pixels, so fall through and decompress... } - return SkKTXFile::WriteBitmapToKTX(stream, bitmap); } diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp index cc1b73baa5..4ad12c84cd 100644 --- a/src/images/SkImageEncoder.cpp +++ b/src/images/SkImageEncoder.cpp @@ -60,3 +60,13 @@ SkData* SkImageEncoder::EncodeData(const SkImageInfo& info, const void* pixels, SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t)); return enc.get() ? enc.get()->encodeData(bm, quality) : nullptr; } + +SkData* SkImageEncoder::EncodeData(const SkPixmap& pmap, Type t, int quality) { + return EncodeData(pmap.info(), pmap.addr(), pmap.rowBytes(), t, quality); +} + +SkData* SkImageEncoder::ReencodeData(SkData* encoded, Type t) { + SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t)); + return enc.get() ? enc.get()->onReencodeData(encoded) : nullptr; +} + |