Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Unified Diff: dm/DMSrcSink.cpp

Issue 1982753002: Ensure that SkColorTable->fCount is set properly after decodes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | include/core/SkColorTable.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dm/DMSrcSink.cpp
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index a98ba41d18823542f20c00a5d3c02b55019f7b31..1155395f4042c34745a9d86285f5f3f6bc5529fd 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -275,7 +275,7 @@ bool CodecSrc::veto(SinkFlags flags) const {
}
// Allows us to test decodes to non-native 8888.
-void swap_rb_if_necessary(SkBitmap& bitmap, CodecSrc::DstColorType dstColorType) {
+static void swap_rb_if_necessary(SkBitmap& bitmap, CodecSrc::DstColorType dstColorType) {
if (CodecSrc::kNonNative8888_Always_DstColorType != dstColorType) {
return;
}
@@ -288,7 +288,7 @@ void swap_rb_if_necessary(SkBitmap& bitmap, CodecSrc::DstColorType dstColorType)
// FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and skbug.com/3339.
// This allows us to still test unpremultiplied decodes.
-void premultiply_if_necessary(SkBitmap& bitmap) {
+static void premultiply_if_necessary(SkBitmap& bitmap) {
if (kUnpremul_SkAlphaType != bitmap.alphaType()) {
return;
}
@@ -316,8 +316,8 @@ void premultiply_if_necessary(SkBitmap& bitmap) {
bitmap.setAlphaType(kPremul_SkAlphaType);
}
-bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType,
- CodecSrc::DstColorType dstColorType) {
+static bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType,
+ CodecSrc::DstColorType dstColorType) {
switch (dstColorType) {
case CodecSrc::kIndex8_Always_DstColorType:
if (kRGB_565_SkColorType == canvasColorType) {
@@ -354,6 +354,17 @@ bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType,
return true;
}
+static void draw_to_canvas(SkCanvas* canvas, const SkImageInfo& info, void* pixels, size_t rowBytes,
+ SkPMColor* colorPtr, int colorCount, CodecSrc::DstColorType dstColorType,
+ SkScalar left = 0, SkScalar top = 0) {
+ SkAutoTUnref<SkColorTable> colorTable(new SkColorTable(colorPtr, colorCount));
+ SkBitmap bitmap;
+ bitmap.installPixels(info, pixels, rowBytes, colorTable.get(), nullptr, nullptr);
+ premultiply_if_necessary(bitmap);
+ swap_rb_if_necessary(bitmap, dstColorType);
+ canvas->drawBitmap(bitmap, left, top);
+}
+
Error CodecSrc::draw(SkCanvas* canvas) const {
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
if (!encoded) {
@@ -383,24 +394,15 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
}
decodeInfo = decodeInfo.makeWH(size.width(), size.height());
- // Construct a color table for the decode if necessary
- SkAutoTUnref<SkColorTable> colorTable(nullptr);
- SkPMColor* colorPtr = nullptr;
- int* colorCountPtr = nullptr;
- int maxColors = 256;
- if (kIndex_8_SkColorType == decodeInfo.colorType()) {
- SkPMColor colors[256];
- colorTable.reset(new SkColorTable(colors, maxColors));
- colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
- colorCountPtr = &maxColors;
- }
+ const int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType());
+ const size_t rowBytes = size.width() * bpp;
+ SkAutoMalloc pixels(decodeInfo.getSafeSize(rowBytes));
+ SkPMColor colorPtr[256];
+ int colorCount = 256;
- SkBitmap bitmap;
- SkPixelRefFactory* factory = nullptr;
- SkMallocPixelRef::ZeroedPRFactory zeroFactory;
SkCodec::Options options;
if (kCodecZeroInit_Mode == fMode) {
- factory = &zeroFactory;
+ memset(pixels.get(), 0, size.height() * rowBytes);
options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
}
@@ -409,16 +411,12 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
kBGRA_8888_SkColorType == decodeInfo.colorType()) {
bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
}
- if (!bitmap.tryAllocPixels(bitmapInfo, factory, colorTable.get())) {
- return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
- decodeInfo.width(), decodeInfo.height());
- }
switch (fMode) {
case kCodecZeroInit_Mode:
case kCodec_Mode: {
- switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options,
- colorPtr, colorCountPtr)) {
+ switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &options,
+ colorPtr, &colorCount)) {
case SkCodec::kSuccess:
// We consider incomplete to be valid, since we should still decode what is
// available.
@@ -428,19 +426,18 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
// Everything else is considered a failure.
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
}
- premultiply_if_necessary(bitmap);
- swap_rb_if_necessary(bitmap, fDstColorType);
- canvas->drawBitmap(bitmap, 0, 0);
+
+ draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount,
+ fDstColorType);
break;
}
case kScanline_Mode: {
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
- colorCountPtr)) {
+ &colorCount)) {
return "Could not start scanline decoder";
}
- void* dst = bitmap.getAddr(0, 0);
- size_t rowBytes = bitmap.rowBytes();
+ void* dst = pixels.get();
uint32_t height = decodeInfo.height();
switch (codec->getScanlineOrder()) {
case SkCodec::kTopDown_SkScanlineOrder:
@@ -453,19 +450,17 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
case SkCodec::kOutOfOrder_SkScanlineOrder: {
for (int y = 0; y < decodeInfo.height(); y++) {
int dstY = codec->outputScanline(y);
- void* dstPtr = bitmap.getAddr(0, dstY);
+ void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
// We complete the loop, even if this call begins to fail
// due to an incomplete image. This ensures any uninitialized
// memory will be filled with the proper value.
- codec->getScanlines(dstPtr, 1, bitmap.rowBytes());
+ codec->getScanlines(dstPtr, 1, rowBytes);
}
break;
}
}
- premultiply_if_necessary(bitmap);
- swap_rb_if_necessary(bitmap, fDstColorType);
- canvas->drawBitmap(bitmap, 0, 0);
+ draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, colorPtr, colorCount, fDstColorType);
break;
}
case kStripe_Mode: {
@@ -474,10 +469,11 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
// does not align with image blocks.
const int stripeHeight = 37;
const int numStripes = (height + stripeHeight - 1) / stripeHeight;
+ void* dst = pixels.get();
// Decode odd stripes
- if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
- colorCountPtr)) {
+ if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, nullptr, colorPtr,
+ &colorCount)) {
return "Could not start scanline decoder";
}
@@ -496,13 +492,14 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
const int startY = (i + 1) * stripeHeight;
const int linesToRead = SkTMin(stripeHeight, height - startY);
if (linesToRead > 0) {
- codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes());
+ codec->getScanlines(SkTAddOffset<void>(dst, rowBytes * startY), linesToRead,
+ rowBytes);
}
}
// Decode even stripes
const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo, nullptr,
- colorPtr, colorCountPtr);
+ colorPtr, &colorCount);
if (SkCodec::kSuccess != startResult) {
return "Failed to restart scanline decoder with same parameters.";
}
@@ -510,7 +507,8 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
// Read a stripe
const int startY = i * stripeHeight;
const int linesToRead = SkTMin(stripeHeight, height - startY);
- codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes());
+ codec->getScanlines(SkTAddOffset<void>(dst, rowBytes * startY), linesToRead,
+ rowBytes);
// Skip a stripe
const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight);
@@ -518,9 +516,8 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
codec->skipScanlines(linesToSkip);
}
}
- premultiply_if_necessary(bitmap);
- swap_rb_if_necessary(bitmap, fDstColorType);
- canvas->drawBitmap(bitmap, 0, 0);
+
+ draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, colorPtr, colorCount, fDstColorType);
break;
}
case kCroppedScanline_Mode: {
@@ -537,16 +534,15 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), height);
opts.fSubset = &subset;
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &opts,
- colorPtr, colorCountPtr)) {
+ colorPtr, &colorCount)) {
return "Could not start scanline decoder.";
}
- codec->getScanlines(bitmap.getAddr(x, 0), height, bitmap.rowBytes());
+ codec->getScanlines(SkTAddOffset<void>(pixels.get(), x * bpp), height, rowBytes);
}
- premultiply_if_necessary(bitmap);
- swap_rb_if_necessary(bitmap, fDstColorType);
- canvas->drawBitmap(bitmap, 0, 0);
+ draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount,
+ fDstColorType);
break;
}
case kSubset_Mode: {
@@ -569,7 +565,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
opts.fSubset = &subset;
SkBitmap subsetBm;
// We will reuse pixel memory from bitmap.
- void* pixels = bitmap.getPixels();
+ void* dst = pixels.get();
// Keep track of left and top (for drawing subsetBm into canvas). We could use
// fScale * x and fScale * y, but we want integers such that the next subset will start
// where the last one ended. So we'll add decodeInfo.width() and height().
@@ -588,13 +584,9 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
const int scaledH = SkTMax(1, SkScalarRoundToInt(preScaleH * fScale));
decodeInfo = decodeInfo.makeWH(scaledW, scaledH);
SkImageInfo subsetBitmapInfo = bitmapInfo.makeWH(scaledW, scaledH);
- size_t rowBytes = subsetBitmapInfo.minRowBytes();
- if (!subsetBm.installPixels(subsetBitmapInfo, pixels, rowBytes, colorTable.get(),
- nullptr, nullptr)) {
- return SkStringPrintf("could not install pixels for %s.", fPath.c_str());
- }
- const SkCodec::Result result = codec->getPixels(decodeInfo, pixels, rowBytes,
- &opts, colorPtr, colorCountPtr);
+ size_t subsetRowBytes = subsetBitmapInfo.minRowBytes();
+ const SkCodec::Result result = codec->getPixels(decodeInfo, dst, subsetRowBytes,
+ &opts, colorPtr, &colorCount);
switch (result) {
case SkCodec::kSuccess:
case SkCodec::kIncompleteInput:
@@ -605,9 +597,10 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
x, y, decodeInfo.width(), decodeInfo.height(),
fPath.c_str(), W, H, result);
}
- premultiply_if_necessary(subsetBm);
- swap_rb_if_necessary(subsetBm, fDstColorType);
- canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToScalar(top));
+ draw_to_canvas(canvas, subsetBitmapInfo, dst, subsetRowBytes, colorPtr,
+ colorCount, fDstColorType, SkIntToScalar(left),
+ SkIntToScalar(top));
+
// translate by the scaled height.
top += decodeInfo.height();
}
@@ -681,17 +674,11 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
}
decodeInfo = decodeInfo.makeWH(size.width(), size.height());
- // Construct a color table for the decode if necessary
- SkAutoTUnref<SkColorTable> colorTable(nullptr);
- SkPMColor* colorPtr = nullptr;
- int* colorCountPtr = nullptr;
- int maxColors = 256;
- if (kIndex_8_SkColorType == decodeInfo.colorType()) {
- SkPMColor colors[256];
- colorTable.reset(new SkColorTable(colors, maxColors));
- colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
- colorCountPtr = &maxColors;
- }
+ int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType());
+ size_t rowBytes = size.width() * bpp;
+ SkAutoMalloc pixels(size.height() * rowBytes);
+ SkPMColor colorPtr[256];
+ int colorCount = 256;
SkBitmap bitmap;
SkImageInfo bitmapInfo = decodeInfo;
@@ -699,27 +686,21 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
kBGRA_8888_SkColorType == decodeInfo.colorType()) {
bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
}
- if (!bitmap.tryAllocPixels(bitmapInfo, nullptr, colorTable.get())) {
- return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
- decodeInfo.width(), decodeInfo.height());
- }
// Create options for the codec.
SkAndroidCodec::AndroidOptions options;
options.fColorPtr = colorPtr;
- options.fColorCount = colorCountPtr;
+ options.fColorCount = &colorCount;
options.fSampleSize = fSampleSize;
- switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options)) {
+ switch (codec->getAndroidPixels(decodeInfo, pixels.get(), rowBytes, &options)) {
case SkCodec::kSuccess:
case SkCodec::kIncompleteInput:
break;
default:
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
}
- premultiply_if_necessary(bitmap);
- swap_rb_if_necessary(bitmap, fDstColorType);
- canvas->drawBitmap(bitmap, 0, 0);
+ draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount, fDstColorType);
return "";
}
@@ -820,31 +801,18 @@ Error ImageGenSrc::draw(SkCanvas* canvas) const {
return Error::Nonfatal("Avoid requesting non-opaque kGray8 decodes.");
}
- SkAutoTUnref<SkColorTable> colorTable(nullptr);
- SkPMColor* colorPtr = nullptr;
- int* colorCountPtr = nullptr;
- int maxColors = 256;
- if (kIndex_8_SkColorType == decodeInfo.colorType()) {
- SkPMColor colors[256];
- colorTable.reset(new SkColorTable(colors, maxColors));
- colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
- colorCountPtr = &maxColors;
- }
+ int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType());
+ size_t rowBytes = decodeInfo.width() * bpp;
+ SkAutoMalloc pixels(decodeInfo.height() * rowBytes);
+ SkPMColor colorPtr[256];
+ int colorCount = 256;
- SkBitmap bitmap;
- if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) {
- return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
- decodeInfo.width(), decodeInfo.height());
- }
-
- if (!gen->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), colorPtr,
- colorCountPtr))
- {
+ if (!gen->getPixels(decodeInfo, pixels.get(), rowBytes, colorPtr, &colorCount)) {
return SkStringPrintf("Image generator could not getPixels() for %s\n", fPath.c_str());
}
- premultiply_if_necessary(bitmap);
- canvas->drawBitmap(bitmap, 0, 0);
+ draw_to_canvas(canvas, decodeInfo, pixels.get(), rowBytes, colorPtr, colorCount,
+ CodecSrc::kGetFromCanvas_DstColorType);
return "";
}
« no previous file with comments | « no previous file | include/core/SkColorTable.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698