SkPixelSerializer: support indexed pixels

By taking a SkPixmap, SkPixelSerializer::encode() can now handle colortables.

Review URL: https://codereview.chromium.org/1501303002
This commit is contained in:
halcanary 2015-12-07 12:42:24 -08:00 committed by Commit bot
parent a6f3047971
commit 6b28017781
4 changed files with 28 additions and 14 deletions

View File

@ -267,7 +267,7 @@ public:
* attempt to reuse existing encoded data (as returned by refEncoded).
*
* We defer to the SkPixelSerializer both for vetting existing encoded data
* (useEncodedData) and for encoding the image (encodePixels) when no such data is
* (useEncodedData) and for encoding the image (encode) when no such data is
* present or is rejected by the serializer.
*
* If not specified, we use a default serializer which 1) always accepts existing data

View File

@ -9,9 +9,9 @@
#define SkPixelSerializer_DEFINED
#include "SkRefCnt.h"
#include "SkPixmap.h"
class SkData;
struct SkImageInfo;
/**
* Interface for serializing pixels, e.g. SkBitmaps in an SkPicture.
@ -32,8 +32,10 @@ public:
* Call to get the client's version of encoding these pixels. If it
* returns NULL, serialize the raw pixels.
*/
SkData* encodePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
return this->onEncodePixels(info, pixels, rowBytes);
SkData* encode(const SkPixmap& pixmap) {
SkData* data = this->onEncode(pixmap);
return data ? data : this->onEncodePixels(
pixmap.info(), pixmap.addr(), pixmap.rowBytes());
}
protected:
@ -47,6 +49,15 @@ protected:
* If you want to encode these pixels, return the encoded data as an SkData
* Return null if you want to serialize the raw pixels.
*/
virtual SkData* onEncodePixels(const SkImageInfo&, const void* pixels, size_t rowBytes) = 0;
// NOTE: onEncodePixels() is deprecated and removed in a later CL.
// Subclasses should implement onEncode() instead. Subclasses
// should implement at least one of onEncodePixels() or
// onUseEncodedData().
virtual SkData* onEncodePixels(const SkImageInfo&,
const void* /*pixels*/,
size_t /*rowBytes*/) {
return nullptr;
}
virtual SkData* onEncode(const SkPixmap&) { return nullptr; }
};
#endif // SkPixelSerializer_DEFINED

View File

@ -200,11 +200,8 @@ 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()));
SkAutoDataUnref data(fPixelSerializer->encode(result.pixmap()));
if (data.get() != nullptr) {
// if we have to "encode" the bitmap, then we assume there is no
// offset to share, since we are effectively creating a new pixelref

View File

@ -185,9 +185,16 @@ 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);
SkData* onEncode(const SkPixmap& pixmap) override {
SkBitmap bm;
if (!bm.installPixels(pixmap.info(),
const_cast<void*>(pixmap.addr()),
pixmap.rowBytes(),
pixmap.ctable(),
nullptr, nullptr)) {
return nullptr;
}
return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
}
};
@ -205,8 +212,7 @@ SkData* SkImage::encode(SkPixelSerializer* serializer) const {
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->encode(apu.pixmap());
}
return nullptr;