aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkPixelSerializer.cpp24
-rw-r--r--src/core/SkWriteBuffer.cpp19
-rw-r--r--src/image/SkImage.cpp22
-rw-r--r--src/images/SkImageDecoder_ktx.cpp36
-rw-r--r--src/images/SkImageEncoder.cpp10
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;
+}
+