Chromium Code Reviews| Index: dm/DMSrcSink.cpp |
| diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp |
| index a98ba41d18823542f20c00a5d3c02b55019f7b31..c3256f14791369dfc09201730cd0b359e9279da7 100644 |
| --- a/dm/DMSrcSink.cpp |
| +++ b/dm/DMSrcSink.cpp |
| @@ -354,6 +354,17 @@ bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType, |
| return true; |
| } |
| +void draw_to_canvas(SkCanvas* canvas, const SkImageInfo& info, void* pixels, size_t rowBytes, |
|
scroggo
2016/05/16 19:28:15
static?
msarett
2016/05/17 15:29:34
Thanks! Also fixing this elsewhere...
|
| + 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; |
| - } |
| + int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType()); |
| + size_t rowBytes = size.width() * bpp; |
|
scroggo
2016/05/16 19:28:15
nit: These variables could be const?
msarett
2016/05/17 15:29:34
Done.
|
| + SkAutoMalloc pixels(size.height() * rowBytes); |
|
scroggo
2016/05/16 19:28:15
I think you could instead call decodeInfo.getSafeS
msarett
2016/05/17 15:29:34
sgtm
|
| + 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 = ⊂ |
| 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 = ⊂ |
| 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 ""; |
| } |