#
'skia_for_chromium_defines': [
'SK_LEGACY_DRAWPICTURECALLBACK',
+ 'SK_SUPPORT_LEGACY_IMAGE_GENERATOR_RETURN',
],
},
}
class SkData;
class SkImageGenerator;
+//#define SK_SUPPORT_LEGACY_IMAGE_GENERATOR_RETURN
+
/**
* Takes ownership of SkImageGenerator. If this method fails for
* whatever reason, it will return false and immediatetely delete
* An interface that allows a purgeable PixelRef (such as a
* SkDiscardablePixelRef) to decode and re-decode an image as needed.
*/
-class SK_API SkImageGenerator {
+class SK_API SkImageGenerator : public SkNoncopyable {
public:
/**
* The PixelRef which takes ownership of this SkImageGenerator
bool getInfo(SkImageInfo* info);
/**
+ * Used to describe the result of a call to getPixels().
+ *
+ * Result is the union of possible results from subclasses.
+ */
+ enum Result {
+ /**
+ * General return value for success.
+ */
+ kSuccess,
+ /**
+ * The input is incomplete. A partial image was generated.
+ */
+ kIncompleteInput,
+ /**
+ * The generator cannot convert to match the request, ignoring
+ * dimensions.
+ */
+ kInvalidConversion,
+ /**
+ * The generator cannot scale to requested size.
+ */
+ kInvalidScale,
+ /**
+ * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
+ * too small, etc.
+ */
+ kInvalidParameters,
+ /**
+ * The input did not contain a valid image.
+ */
+ kInvalidInput,
+ /**
+ * Fulfilling this request requires rewinding the input, which is not
+ * supported for this input.
+ */
+ kCouldNotRewind,
+ /**
+ * This method is not implemented by this generator.
+ */
+ kUnimplemented,
+ };
+
+ /**
* Decode into the given pixels, a block of memory of size at
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
* bytesPerPixel)
* different output-configs, which the implementation can
* decide to support or not.
*
+ * A size that does not match getInfo() implies a request
+ * to scale. If the generator cannot perform this scale,
+ * it will return kInvalidScale.
+ *
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
* (where N is the logical number of table entries) and set ctableCount to N.
* If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
* is not null, it will be set to 0.
*
- * @return false if anything goes wrong or if the image info is
- * unsupported.
+ * @return Result kSuccess, or another value explaining the type of failure.
*/
- bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- SkPMColor ctable[], int* ctableCount);
+ Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount);
/**
* Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType.
*/
- bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
+ Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
/**
* If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
protected:
virtual SkData* onRefEncodedData();
virtual bool onGetInfo(SkImageInfo* info);
+#ifdef SK_SUPPORT_LEGACY_IMAGE_GENERATOR_RETURN
virtual bool onGetPixels(const SkImageInfo& info,
void* pixels, size_t rowBytes,
SkPMColor ctable[], int* ctableCount);
+#endif
+ // TODO (scroggo): rename to onGetPixels.
+ virtual Result onGetPixelsEnum(const SkImageInfo& info,
+ void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount);
virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
SkYUVColorSpace* colorSpace);
return this->onGetInfo(info);
}
-bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- SkPMColor ctable[], int* ctableCount) {
+SkImageGenerator::Result SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels,
+ size_t rowBytes, SkPMColor ctable[],
+ int* ctableCount) {
if (kUnknown_SkColorType == info.colorType()) {
- return false;
+ return kInvalidConversion;
}
if (NULL == pixels) {
- return false;
+ return kInvalidParameters;
}
if (rowBytes < info.minRowBytes()) {
- return false;
+ return kInvalidParameters;
}
if (kIndex_8_SkColorType == info.colorType()) {
if (NULL == ctable || NULL == ctableCount) {
- return false;
+ return kInvalidParameters;
}
} else {
if (ctableCount) {
ctable = NULL;
}
- bool success = this->onGetPixels(info, pixels, rowBytes, ctable, ctableCount);
+ const Result result = this->onGetPixelsEnum(info, pixels, rowBytes, ctable, ctableCount);
- if (success && ctableCount) {
+ if ((kIncompleteInput == result || kSuccess == result) && ctableCount) {
SkASSERT(*ctableCount >= 0 && *ctableCount <= 256);
}
- return success;
+ return result;
}
-bool SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+SkImageGenerator::Result 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 kInvalidConversion;
}
return this->getPixels(info, pixels, rowBytes, NULL, NULL);
}
return false;
}
-bool SkImageGenerator::onGetPixels(const SkImageInfo&, void*, size_t, SkPMColor*, int*) {
- return false;
+#ifdef SK_SUPPORT_LEGACY_IMAGE_GENERATOR_RETURN
+bool SkImageGenerator::onGetPixels(const SkImageInfo&, void*, size_t,
+ SkPMColor*, int*) {
+ return kUnimplemented;
+}
+#endif
+SkImageGenerator::Result SkImageGenerator::onGetPixelsEnum(const SkImageInfo& info, void* pixels,
+ size_t rowBytes, SkPMColor* colors,
+ int* colorCount) {
+#ifdef SK_SUPPORT_LEGACY_IMAGE_GENERATOR_RETURN
+ if (this->onGetPixels(info, pixels, rowBytes, colors, colorCount)) {
+ return kSuccess;
+ }
+#endif
+ return kUnimplemented;
}
*info = fInfo;
return true;
}
- virtual bool onGetPixels(const SkImageInfo& info,
- void* pixels, size_t rowBytes,
- SkPMColor ctable[], int* ctableCount) SK_OVERRIDE;
+ virtual Result onGetPixelsEnum(const SkImageInfo& info,
+ void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount) SK_OVERRIDE;
virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
SkYUVColorSpace* colorSpace) SK_OVERRIDE;
return SkSafeRef(fData);
}
-bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info,
- void* pixels, size_t rowBytes,
- SkPMColor ctableEntries[], int* ctableCount) {
+SkImageGenerator::Result DecodingImageGenerator::onGetPixelsEnum(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.dimensions() != fInfo.dimensions()) {
+ return kInvalidScale;
+ }
+ return kInvalidConversion;
}
SkAssertResult(fStream->rewind());
SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
if (NULL == decoder.get()) {
- return false;
+ return kInvalidInput;
}
decoder->setDitherImage(fDitherImage);
decoder->setSampleSize(fSampleSize);
SkBitmap bitmap;
TargetAllocator allocator(fInfo, pixels, rowBytes);
decoder->setAllocator(&allocator);
- bool success = decoder->decode(fStream, &bitmap, info.colorType(),
- SkImageDecoder::kDecodePixels_Mode) != SkImageDecoder::kFailure;
+ const SkImageDecoder::Result decodeResult = decoder->decode(fStream, &bitmap, info.colorType(),
+ SkImageDecoder::kDecodePixels_Mode);
decoder->setAllocator(NULL);
- if (!success) {
- return false;
+ if (SkImageDecoder::kFailure == decodeResult) {
+ return kInvalidInput;
}
if (allocator.isReady()) { // Did not use pixels!
SkBitmap bm;
if (!copySuccess || allocator.isReady()) {
SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
// Earlier we checked canCopyto(); we expect consistency.
- return false;
+ return kInvalidConversion;
}
SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
} else {
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
+ // they asked for Index8, but we didn't receive that from decoder
+ return kInvalidConversion;
}
SkColorTable* ctable = bitmap.getColorTable();
if (NULL == ctable) {
- return false;
+ return kInvalidConversion;
}
const int count = ctable->count();
memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor));
*ctableCount = count;
}
- return true;
+ if (SkImageDecoder::kPartialSuccess == decodeResult) {
+ return kIncompleteInput;
+ }
+ return kSuccess;
}
bool DecodingImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3],
fErrorInDecoding = true;
return false;
}
- if (!fImageGenerator->getPixels(info, fLockedBitmap.getPixels(), fRowBytes)) {
- fErrorInDecoding = true;
- return false;
+ const SkImageGenerator::Result result = fImageGenerator->getPixels(info,
+ fLockedBitmap.getPixels(), fRowBytes);
+ switch (result) {
+ case SkImageGenerator::kIncompleteInput:
+ case SkImageGenerator::kSuccess:
+ break;
+ default:
+ fErrorInDecoding = true;
+ return false;
}
fLockedBitmap.setImmutable();
SkBitmapCache::Add(
SkPMColor colors[256];
int colorCount = 0;
- if (!fGenerator->getPixels(info, pixels, fRowBytes, colors, &colorCount)) {
- fDiscardableMemory->unlock();
- SkDELETE(fDiscardableMemory);
- fDiscardableMemory = NULL;
- return false;
+ const SkImageGenerator::Result result = fGenerator->getPixels(info, pixels, fRowBytes,
+ colors, &colorCount);
+ switch (result) {
+ case SkImageGenerator::kSuccess:
+ case SkImageGenerator::kIncompleteInput:
+ break;
+ default:
+ fDiscardableMemory->unlock();
+ SkDELETE(fDiscardableMemory);
+ fDiscardableMemory = NULL;
+ return false;
}
// Note: our ctable is not purgeable, as it is not stored in the discardablememory block.
return true;
}
- virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- SkPMColor ctableEntries[], int* ctableCount) SK_OVERRIDE {
+ virtual Result onGetPixelsEnum(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor ctableEntries[], int* ctableCount) SK_OVERRIDE {
SkMemoryStream stream(fData->data(), fData->size(), false);
SkAutoTUnref<BareMemoryAllocator> allocator(SkNEW_ARGS(BareMemoryAllocator,
(info, pixels, rowBytes)));
fDecoder->setRequireUnpremultipliedColors(kUnpremul_SkAlphaType == info.alphaType());
SkBitmap bm;
- SkImageDecoder::Result result = fDecoder->decode(&stream, &bm, info.colorType(),
- SkImageDecoder::kDecodePixels_Mode);
- switch (result) {
- case SkImageDecoder::kSuccess:
- break;
- default:
- return false;
+ const SkImageDecoder::Result result = fDecoder->decode(&stream, &bm, info.colorType(),
+ SkImageDecoder::kDecodePixels_Mode);
+ if (SkImageDecoder::kFailure == result) {
+ return kInvalidInput;
}
SkASSERT(info.colorType() == bm.info().colorType());
SkColorTable* ctable = bm.getColorTable();
if (NULL == ctable) {
- return false;
+ return kInvalidConversion;
}
const int count = ctable->count();
memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor));
*ctableCount = count;
}
- return true;
+ if (SkImageDecoder::kPartialSuccess == result) {
+ return kIncompleteInput;
+ }
+ return kSuccess;
}
bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
return true;
}
- virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- SkPMColor ctable[], int* ctableCount) SK_OVERRIDE {
+ virtual Result onGetPixelsEnum(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor ctable[], int* ctableCount) SK_OVERRIDE {
REPORTER_ASSERT(fReporter, pixels != NULL);
- size_t minRowBytes = static_cast<size_t>(info.width() * info.bytesPerPixel());
- REPORTER_ASSERT(fReporter, rowBytes >= minRowBytes);
- if ((NULL == pixels)
- || (fType != kSucceedGetPixels_TestType)
- || (info.colorType() != kN32_SkColorType)) {
- return false;
+ REPORTER_ASSERT(fReporter, rowBytes >= info.minRowBytes());
+ if (fType != kSucceedGetPixels_TestType) {
+ return kUnimplemented;
+ }
+ if (info.colorType() != kN32_SkColorType) {
+ return kInvalidConversion;
}
char* bytePtr = static_cast<char*>(pixels);
for (int y = 0; y < info.height(); ++y) {
TestImageGenerator::Color(), info.width());
bytePtr += rowBytes;
}
- return true;
+ return kSuccess;
}
private: