Index: src/ports/SkImageDecoder_WIC.cpp |
diff --git a/src/ports/SkImageDecoder_WIC.cpp b/src/ports/SkImageDecoder_WIC.cpp |
index c7222e635a993f97f5e07ee0bc140f64b1864f5b..ef6de00dc93335bbbb967711eb53cc0f02fb729d 100644 |
--- a/src/ports/SkImageDecoder_WIC.cpp |
+++ b/src/ports/SkImageDecoder_WIC.cpp |
@@ -31,7 +31,6 @@ |
#include <wincodec.h> |
#include "SkAutoCoInitialize.h" |
-#include "SkImageDecoder.h" |
#include "SkImageEncoder.h" |
#include "SkIStream.h" |
#include "SkMovie.h" |
@@ -48,222 +47,6 @@ |
#undef CLSID_WICImagingFactory |
#endif |
-class SkImageDecoder_WIC : public SkImageDecoder { |
-public: |
- // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode for decoding |
- // only the format. |
- enum WICModes { |
- kDecodeFormat_WICMode, |
- kDecodeBounds_WICMode, |
- kDecodePixels_WICMode, |
- }; |
- |
- /** |
- * Helper function to decode an SkStream. |
- * @param stream SkStream to decode. Must be at the beginning. |
- * @param bm SkBitmap to decode into. Only used if wicMode is kDecodeBounds_WICMode or |
- * kDecodePixels_WICMode, in which case it must not be nullptr. |
- * @param format Out parameter for the SkImageDecoder::Format of the SkStream. Only used if |
- * wicMode is kDecodeFormat_WICMode. |
- */ |
- bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format* format) const; |
- |
-protected: |
- Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override; |
-}; |
- |
-struct FormatConversion { |
- GUID fGuidFormat; |
- SkImageDecoder::Format fFormat; |
-}; |
- |
-static const FormatConversion gFormatConversions[] = { |
- { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format }, |
- { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format }, |
- { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format }, |
- { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format }, |
- { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format }, |
-}; |
- |
-static SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) { |
- for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { |
- if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) { |
- return gFormatConversions[i].fFormat; |
- } |
- } |
- return SkImageDecoder::kUnknown_Format; |
-} |
- |
-SkImageDecoder::Result SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
- WICModes wicMode; |
- switch (mode) { |
- case SkImageDecoder::kDecodeBounds_Mode: |
- wicMode = kDecodeBounds_WICMode; |
- break; |
- case SkImageDecoder::kDecodePixels_Mode: |
- wicMode = kDecodePixels_WICMode; |
- break; |
- } |
- return this->decodeStream(stream, bm, wicMode, nullptr) ? kSuccess : kFailure; |
-} |
- |
-bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, |
- Format* format) const { |
- //Initialize COM. |
- SkAutoCoInitialize scopedCo; |
- if (!scopedCo.succeeded()) { |
- return false; |
- } |
- |
- HRESULT hr = S_OK; |
- |
- //Create Windows Imaging Component ImagingFactory. |
- SkTScopedComPtr<IWICImagingFactory> piImagingFactory; |
- if (SUCCEEDED(hr)) { |
- hr = CoCreateInstance( |
- CLSID_WICImagingFactory |
- , nullptr |
- , CLSCTX_INPROC_SERVER |
- , IID_PPV_ARGS(&piImagingFactory) |
- ); |
- } |
- |
- //Convert SkStream to IStream. |
- SkTScopedComPtr<IStream> piStream; |
- if (SUCCEEDED(hr)) { |
- hr = SkIStream::CreateFromSkStream(stream, false, &piStream); |
- } |
- |
- //Make sure we're at the beginning of the stream. |
- if (SUCCEEDED(hr)) { |
- LARGE_INTEGER liBeginning = { 0 }; |
- hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, nullptr); |
- } |
- |
- //Create the decoder from the stream content. |
- SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder; |
- if (SUCCEEDED(hr)) { |
- hr = piImagingFactory->CreateDecoderFromStream( |
- piStream.get() //Image to be decoded |
- , nullptr //No particular vendor |
- , WICDecodeMetadataCacheOnDemand //Cache metadata when needed |
- , &piBitmapDecoder //Pointer to the decoder |
- ); |
- } |
- |
- if (kDecodeFormat_WICMode == wicMode) { |
- SkASSERT(format != nullptr); |
- //Get the format |
- if (SUCCEEDED(hr)) { |
- GUID guidFormat; |
- hr = piBitmapDecoder->GetContainerFormat(&guidFormat); |
- if (SUCCEEDED(hr)) { |
- *format = GuidContainerFormat_to_Format(guidFormat); |
- return true; |
- } |
- } |
- return false; |
- } |
- |
- //Get the first frame from the decoder. |
- SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode; |
- if (SUCCEEDED(hr)) { |
- hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode); |
- } |
- |
- //Get the BitmapSource interface of the frame. |
- SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal; |
- if (SUCCEEDED(hr)) { |
- hr = piBitmapFrameDecode->QueryInterface( |
- IID_PPV_ARGS(&piBitmapSourceOriginal) |
- ); |
- } |
- |
- //Get the size of the bitmap. |
- UINT width; |
- UINT height; |
- if (SUCCEEDED(hr)) { |
- hr = piBitmapSourceOriginal->GetSize(&width, &height); |
- } |
- |
- //Exit early if we're only looking for the bitmap bounds. |
- if (SUCCEEDED(hr)) { |
- bm->setInfo(SkImageInfo::MakeN32Premul(width, height)); |
- if (kDecodeBounds_WICMode == wicMode) { |
- return true; |
- } |
- if (!this->allocPixelRef(bm, nullptr)) { |
- return false; |
- } |
- } |
- |
- //Create a format converter. |
- SkTScopedComPtr<IWICFormatConverter> piFormatConverter; |
- if (SUCCEEDED(hr)) { |
- hr = piImagingFactory->CreateFormatConverter(&piFormatConverter); |
- } |
- |
- GUID destinationPixelFormat; |
- if (this->getRequireUnpremultipliedColors()) { |
- destinationPixelFormat = GUID_WICPixelFormat32bppBGRA; |
- } else { |
- destinationPixelFormat = GUID_WICPixelFormat32bppPBGRA; |
- } |
- |
- if (SUCCEEDED(hr)) { |
- hr = piFormatConverter->Initialize( |
- piBitmapSourceOriginal.get() //Input bitmap to convert |
- , destinationPixelFormat //Destination pixel format |
- , WICBitmapDitherTypeNone //Specified dither patterm |
- , nullptr //Specify a particular palette |
- , 0.f //Alpha threshold |
- , WICBitmapPaletteTypeCustom //Palette translation type |
- ); |
- } |
- |
- //Get the BitmapSource interface of the format converter. |
- SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted; |
- if (SUCCEEDED(hr)) { |
- hr = piFormatConverter->QueryInterface( |
- IID_PPV_ARGS(&piBitmapSourceConverted) |
- ); |
- } |
- |
- //Copy the pixels into the bitmap. |
- if (SUCCEEDED(hr)) { |
- SkAutoLockPixels alp(*bm); |
- bm->eraseColor(SK_ColorTRANSPARENT); |
- const UINT stride = (UINT) bm->rowBytes(); |
- hr = piBitmapSourceConverted->CopyPixels( |
- nullptr, //Get all the pixels |
- stride, |
- stride * height, |
- reinterpret_cast<BYTE *>(bm->getPixels()) |
- ); |
- |
- // Note: we don't need to premultiply here since we specified PBGRA |
- if (SkBitmap::ComputeIsOpaque(*bm)) { |
- bm->setAlphaType(kOpaque_SkAlphaType); |
- } |
- } |
- |
- return SUCCEEDED(hr); |
-} |
- |
-///////////////////////////////////////////////////////////////////////// |
- |
-extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); |
- |
-SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) { |
- SkImageDecoder* decoder = image_decoder_from_stream(stream); |
- if (nullptr == decoder) { |
- // If no image decoder specific to the stream exists, use SkImageDecoder_WIC. |
- return new SkImageDecoder_WIC; |
- } else { |
- return decoder; |
- } |
-} |
- |
///////////////////////////////////////////////////////////////////////// |
SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) { |
@@ -275,6 +58,10 @@ SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) { |
class SkImageEncoder_WIC : public SkImageEncoder { |
public: |
SkImageEncoder_WIC(Type t) : fType(t) {} |
+ |
+ // DO NOT USE this constructor. This exists only so SkForceLinking can |
+ // link the WIC image encoder. |
+ SkImageEncoder_WIC() {} |
protected: |
virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); |
@@ -451,15 +238,6 @@ static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { |
static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory); |
-static SkImageDecoder::Format get_format_wic(SkStreamRewindable* stream) { |
- SkImageDecoder::Format format; |
- SkImageDecoder_WIC codec; |
- if (!codec.decodeStream(stream, nullptr, SkImageDecoder_WIC::kDecodeFormat_WICMode, &format)) { |
- format = SkImageDecoder::kUnknown_Format; |
- } |
- return format; |
-} |
- |
-static SkImageDecoder_FormatReg gFormatReg(get_format_wic); |
+DEFINE_ENCODER_CREATOR(ImageEncoder_WIC); |
#endif // defined(SK_BUILD_FOR_WIN32) |