Revert "Revert of add colortable support to imagegenerator (https://codereview.chromium.org/304443003/)"
Fix is to add colortable param to installPixels()
This reverts commit 924205aaf2e0c3c65dda13e0eaccde3e7b2a5c40.
BUG=skia:
R=scroggo@google.com, reed@chromium.org
Author: reed@google.com
Review URL: https://codereview.chromium.org/300263005
git-svn-id: http://skia.googlecode.com/svn/trunk@14958 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index a89ca35..0bfcb6f 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -442,16 +442,14 @@
return true;
}
-bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb,
- void (*releaseProc)(void* addr, void* context),
- void* context) {
+bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb, SkColorTable* ct,
+ void (*releaseProc)(void* addr, void* context), void* context) {
if (!this->setConfig(info, rb)) {
this->reset();
return false;
}
- SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, NULL, pixels,
- releaseProc, context);
+ SkPixelRef* pr = SkMallocPixelRef::NewWithProc(info, rb, ct, pixels, releaseProc, context);
if (!pr) {
this->reset();
return false;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 6500212..7e10504 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1114,8 +1114,7 @@
bool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const {
if (fAddr) {
- return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes,
- NULL, NULL);
+ return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes);
} else {
bitmap->reset();
return false;
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index b0af040..aaf4235 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -242,7 +242,7 @@
mask->fBounds.height(),
kAlpha_8_SkColorType,
kPremul_SkAlphaType),
- mask->fImage, mask->fRowBytes, NULL, NULL);
+ mask->fImage, mask->fRowBytes);
SkCanvas canvas(bitmap);
canvas.translate(-SkIntToScalar(mask->fBounds.left()),
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 7a8091c..3be7d84 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -94,8 +94,9 @@
{
data->ref();
void* addr = const_cast<void*>(data->data());
+ SkColorTable* ctable = NULL;
- fBitmap.installPixels(info, addr, rowBytes, release_data, data);
+ fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
fBitmap.setImmutable();
fBitmap.lockPixels();
}
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index b3924a7..2493d89 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -23,12 +23,6 @@
class DecodingImageGenerator : public SkImageGenerator {
public:
virtual ~DecodingImageGenerator();
- virtual SkData* refEncodedData() SK_OVERRIDE;
- // This implementaion of getInfo() always returns true.
- virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE;
- virtual bool getPixels(const SkImageInfo& info,
- void* pixels,
- size_t rowBytes) SK_OVERRIDE;
SkData* fData;
SkStreamRewindable* fStream;
@@ -41,6 +35,18 @@
const SkImageInfo& info,
int sampleSize,
bool ditherImage);
+
+protected:
+ virtual SkData* onRefEncodedData() SK_OVERRIDE;
+ virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
+ *info = fInfo;
+ return true;
+ }
+ virtual bool onGetPixels(const SkImageInfo& info,
+ void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount) SK_OVERRIDE;
+
+private:
typedef SkImageGenerator INHERITED;
};
@@ -69,7 +75,7 @@
// TODO(halcanary): verify that all callers of this function
// will respect new RowBytes. Will be moot once rowbytes belongs
// to PixelRef.
- bm->installPixels(fInfo, fTarget, fRowBytes, NULL, NULL);
+ bm->installPixels(fInfo, fTarget, fRowBytes, ct, NULL, NULL);
fTarget = NULL; // never alloc same pixels twice!
return true;
@@ -123,14 +129,7 @@
fStream->unref();
}
-bool DecodingImageGenerator::getInfo(SkImageInfo* info) {
- if (info != NULL) {
- *info = fInfo;
- }
- return true;
-}
-
-SkData* DecodingImageGenerator::refEncodedData() {
+SkData* DecodingImageGenerator::onRefEncodedData() {
// This functionality is used in `gm --serialize`
// Does not encode options.
if (fData != NULL) {
@@ -151,22 +150,15 @@
return SkSafeRef(fData);
}
-bool DecodingImageGenerator::getPixels(const SkImageInfo& info,
- void* pixels,
- size_t rowBytes) {
- if (NULL == pixels) {
- return false;
- }
+bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info,
+ void* pixels, size_t rowBytes,
+ SkPMColor ctableEntries[], int* ctableCount) {
if (fInfo != info) {
// The caller has specified a different info. This is an
// error for this kind of SkImageGenerator. Use the Options
// to change the settings.
return false;
}
- if (info.minRowBytes() > rowBytes) {
- // The caller has specified a bad rowBytes.
- return false;
- }
SkAssertResult(fStream->rewind());
SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
@@ -202,6 +194,20 @@
} else {
SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
}
+
+ if (kIndex_8_SkColorType == info.colorType()) {
+ if (kIndex_8_SkColorType != bitmap.colorType()) {
+ return false; // they asked for Index8, but we didn't receive that from decoder
+ }
+ SkColorTable* ctable = bitmap.getColorTable();
+ if (NULL == ctable) {
+ return false;
+ }
+ const int count = ctable->count();
+ memcpy(ctableEntries, ctable->lockColors(), count * sizeof(SkPMColor));
+ ctable->unlockColors();
+ *ctableCount = count;
+ }
return true;
}
@@ -214,11 +220,6 @@
const SkDecodingImageGenerator::Options& opts) {
SkASSERT(stream);
SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this.
- if (opts.fUseRequestedColorType &&
- (kIndex_8_SkColorType == opts.fRequestedColorType)) {
- // We do not support indexed color with SkImageGenerators,
- return NULL;
- }
SkAssertResult(autoStream->rewind());
SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream));
if (NULL == decoder.get()) {
@@ -227,24 +228,16 @@
SkBitmap bitmap;
decoder->setSampleSize(opts.fSampleSize);
decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul);
- if (!decoder->decode(stream, &bitmap,
- SkImageDecoder::kDecodeBounds_Mode)) {
+ if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) {
return NULL;
}
- if (bitmap.config() == SkBitmap::kNo_Config) {
+ if (kUnknown_SkColorType == bitmap.colorType()) {
return NULL;
}
SkImageInfo info = bitmap.info();
- if (!opts.fUseRequestedColorType) {
- // Use default
- if (kIndex_8_SkColorType == bitmap.colorType()) {
- // We don't support kIndex8 because we don't support
- // colortables in this workflow.
- info.fColorType = kN32_SkColorType;
- }
- } else {
+ if (opts.fUseRequestedColorType && (opts.fRequestedColorType != info.colorType())) {
if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
return NULL; // Can not translate to needed config.
diff --git a/src/images/SkImageGenerator.cpp b/src/images/SkImageGenerator.cpp
new file mode 100644
index 0000000..daa55a3
--- /dev/null
+++ b/src/images/SkImageGenerator.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkImageGenerator.h"
+
+#ifndef SK_SUPPORT_LEGACY_IMAGEGENERATORAPI
+bool SkImageGenerator::getInfo(SkImageInfo* info) {
+ SkImageInfo dummy;
+ if (NULL == info) {
+ info = &dummy;
+ }
+ return this->onGetInfo(info);
+}
+
+bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount) {
+ if (kUnknown_SkColorType == info.colorType()) {
+ return false;
+ }
+ if (NULL == pixels) {
+ return false;
+ }
+ if (rowBytes < info.minRowBytes()) {
+ return false;
+ }
+
+ if (kIndex_8_SkColorType == info.colorType()) {
+ if (NULL == ctable || NULL == ctableCount) {
+ return false;
+ }
+ } else {
+ if (ctableCount) {
+ *ctableCount = 0;
+ }
+ ctableCount = NULL;
+ ctable = NULL;
+ }
+
+ bool success = this->onGetPixels(info, pixels, rowBytes, ctable, ctableCount);
+
+ if (success && ctableCount) {
+ SkASSERT(*ctableCount >= 0 && *ctableCount <= 256);
+ }
+ return success;
+}
+
+bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+ SkASSERT(kIndex_8_SkColorType != info.colorType());
+ if (kIndex_8_SkColorType == info.colorType()) {
+ return false;
+ }
+ return this->getPixels(info, pixels, rowBytes, NULL, NULL);
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+SkData* SkImageGenerator::onRefEncodedData() {
+ return NULL;
+}
+
+bool SkImageGenerator::onGetInfo(SkImageInfo*) {
+ return false;
+}
+
+bool SkImageGenerator::onGetPixels(const SkImageInfo&, void*, size_t, SkPMColor*, int*) {
+ return false;
+}
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
index ccf812c..b0bbd27 100644
--- a/src/lazy/SkDiscardablePixelRef.cpp
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -60,15 +60,30 @@
}
void* pixels = fDiscardableMemory->data();
- if (!fGenerator->getPixels(this->info(), pixels, fRowBytes)) {
+ const SkImageInfo& info = this->info();
+ SkPMColor colors[256];
+ int colorCount = 0;
+
+ if (!fGenerator->getPixels(info, pixels, fRowBytes, colors, &colorCount)) {
fDiscardableMemory->unlock();
SkDELETE(fDiscardableMemory);
fDiscardableMemory = NULL;
return false;
}
+ // Note: our ctable is not purgable, as it is not stored in the discardablememory block.
+ // This is because SkColorTable is refcntable, and therefore our caller could hold onto it
+ // beyond the scope of a lock/unlock. If we change the API/lifecycle for SkColorTable, we
+ // could move it into the block, but then again perhaps it is small enough that this doesn't
+ // really matter.
+ if (colorCount > 0) {
+ fCTable.reset(SkNEW_ARGS(SkColorTable, (colors, colorCount)));
+ } else {
+ fCTable.reset(NULL);
+ }
+
rec->fPixels = pixels;
- rec->fColorTable = NULL;
+ rec->fColorTable = fCTable.get();
rec->fRowBytes = fRowBytes;
return true;
}
diff --git a/src/lazy/SkDiscardablePixelRef.h b/src/lazy/SkDiscardablePixelRef.h
index e5e1c9f..52a1d6c 100644
--- a/src/lazy/SkDiscardablePixelRef.h
+++ b/src/lazy/SkDiscardablePixelRef.h
@@ -17,10 +17,6 @@
* A PixelRef backed by SkDiscardableMemory, with the ability to
* re-generate the pixels (via a SkImageGenerator) if the DM is
* purged.
- *
- * Since SkColorTable is reference-counted, we do not support indexed
- * color with this class; there would be no way for the discardable
- * memory system to unref the color table.
*/
class SkDiscardablePixelRef : public SkPixelRef {
public:
@@ -46,6 +42,7 @@
// PixelRef, since the SkBitmap doesn't expect them to change.
SkDiscardableMemory* fDiscardableMemory;
+ SkAutoTUnref<SkColorTable> fCTable;
/* Takes ownership of SkImageGenerator. */
SkDiscardablePixelRef(const SkImageInfo&, SkImageGenerator*,
diff --git a/src/utils/SkCanvasStateUtils.cpp b/src/utils/SkCanvasStateUtils.cpp
index 64f62dd..eaee61b 100644
--- a/src/utils/SkCanvasStateUtils.cpp
+++ b/src/utils/SkCanvasStateUtils.cpp
@@ -291,8 +291,7 @@
bitmap.installPixels(SkImageInfo::Make(layerState.width, layerState.height,
colorType, kPremul_SkAlphaType),
- layerState.raster.pixels, layerState.raster.rowBytes,
- NULL, NULL);
+ layerState.raster.pixels, layerState.raster.rowBytes);
SkASSERT(!bitmap.empty());
SkASSERT(!bitmap.isNull());