| Index: src/ports/SkImageEncoder_WIC.cpp
|
| diff --git a/src/ports/SkImageEncoder_WIC.cpp b/src/ports/SkImageEncoder_WIC.cpp
|
| index 5523ea2e11e267e13ad049e48752043a5bf5c9e8..9be95727cad2b0cd16d82da44ae46def4cbc6092 100644
|
| --- a/src/ports/SkImageEncoder_WIC.cpp
|
| +++ b/src/ports/SkImageEncoder_WIC.cpp
|
| @@ -83,35 +83,49 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
| return false;
|
| }
|
|
|
| - //Convert to 8888 if needed.
|
| - const SkBitmap* bitmap;
|
| - SkBitmap bitmapCopy;
|
| - if (kN32_SkColorType == bitmapOrig.colorType() && bitmapOrig.isOpaque()) {
|
| - bitmap = &bitmapOrig;
|
| - } else {
|
| - if (!bitmapOrig.copyTo(&bitmapCopy, kN32_SkColorType)) {
|
| - return false;
|
| - }
|
| - bitmap = &bitmapCopy;
|
| + // First convert to BGRA if necessary.
|
| + SkBitmap bitmap;
|
| + if (!bitmapOrig.copyTo(&bitmap, kBGRA_8888_SkColorType)) {
|
| + return false;
|
| }
|
|
|
| - // We cannot use PBGRA so we need to unpremultiply ourselves
|
| - if (!bitmap->isOpaque()) {
|
| - SkAutoLockPixels alp(*bitmap);
|
| -
|
| - uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels());
|
| - for (int y = 0; y < bitmap->height(); ++y) {
|
| - for (int x = 0; x < bitmap->width(); ++x) {
|
| - uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->bytesPerPixel();
|
| -
|
| + // WIC expects unpremultiplied pixels. Unpremultiply if necessary.
|
| + if (kPremul_SkAlphaType == bitmap.alphaType()) {
|
| + uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap.getPixels());
|
| + for (int y = 0; y < bitmap.height(); ++y) {
|
| + for (int x = 0; x < bitmap.width(); ++x) {
|
| + uint8_t* bytes = pixels + y * bitmap.rowBytes() + x * bitmap.bytesPerPixel();
|
| SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes);
|
| SkColor* dst = reinterpret_cast<SkColor*>(bytes);
|
| -
|
| *dst = SkUnPreMultiply::PMColorToColor(*src);
|
| }
|
| }
|
| }
|
|
|
| + // Finally, if we are performing a jpeg encode, we must convert to BGR.
|
| + void* pixels = bitmap.getPixels();
|
| + size_t rowBytes = bitmap.rowBytes();
|
| + SkAutoMalloc pixelStorage;
|
| + WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
|
| + if (kJPEG_Type == fType) {
|
| + formatDesired = GUID_WICPixelFormat24bppBGR;
|
| + rowBytes = SkAlign4(bitmap.width() * 3);
|
| + pixelStorage.reset(rowBytes * bitmap.height());
|
| + for (int y = 0; y < bitmap.height(); y++) {
|
| + uint8_t* dstRow = SkTAddOffset<uint8_t>(pixelStorage.get(), y * rowBytes);
|
| + for (int x = 0; x < bitmap.width(); x++) {
|
| + uint32_t bgra = *bitmap.getAddr32(x, y);
|
| + dstRow[0] = (uint8_t) (bgra >> 0);
|
| + dstRow[1] = (uint8_t) (bgra >> 8);
|
| + dstRow[2] = (uint8_t) (bgra >> 16);
|
| + dstRow += 3;
|
| + }
|
| + }
|
| +
|
| + pixels = pixelStorage.get();
|
| + }
|
| +
|
| +
|
| //Initialize COM.
|
| SkAutoCoInitialize scopedCo;
|
| if (!scopedCo.succeeded()) {
|
| @@ -176,15 +190,14 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
| }
|
|
|
| //Set the size of the frame.
|
| - const UINT width = bitmap->width();
|
| - const UINT height = bitmap->height();
|
| + const UINT width = bitmap.width();
|
| + const UINT height = bitmap.height();
|
| if (SUCCEEDED(hr)) {
|
| hr = piBitmapFrameEncode->SetSize(width, height);
|
| }
|
|
|
| //Set the pixel format of the frame. If native encoded format cannot match BGRA,
|
| //it will choose the closest pixel format that it supports.
|
| - const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
|
| WICPixelFormatGUID formatGUID = formatDesired;
|
| if (SUCCEEDED(hr)) {
|
| hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID);
|
| @@ -196,13 +209,10 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream
|
|
|
| //Write the pixels into the frame.
|
| if (SUCCEEDED(hr)) {
|
| - SkAutoLockPixels alp(*bitmap);
|
| - const UINT stride = (UINT) bitmap->rowBytes();
|
| - hr = piBitmapFrameEncode->WritePixels(
|
| - height
|
| - , stride
|
| - , stride * height
|
| - , reinterpret_cast<BYTE*>(bitmap->getPixels()));
|
| + hr = piBitmapFrameEncode->WritePixels(height,
|
| + (UINT) rowBytes,
|
| + (UINT) rowBytes * height,
|
| + reinterpret_cast<BYTE*>(pixels));
|
| }
|
|
|
| if (SUCCEEDED(hr)) {
|
| @@ -223,6 +233,7 @@ static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) {
|
| case SkImageEncoder::kBMP_Type:
|
| case SkImageEncoder::kICO_Type:
|
| case SkImageEncoder::kPNG_Type:
|
| + case SkImageEncoder::kJPEG_Type:
|
| break;
|
| default:
|
| return nullptr;
|
|
|