diff options
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/SkImageDecoder_CG.cpp | 247 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_WIC.cpp | 228 | ||||
-rw-r--r-- | src/ports/SkImageDecoder_empty.cpp | 63 |
3 files changed, 0 insertions, 538 deletions
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp index c4446ae16d..6673c240ef 100644 --- a/src/ports/SkImageDecoder_CG.cpp +++ b/src/ports/SkImageDecoder_CG.cpp @@ -11,7 +11,6 @@ #include "SkCGUtils.h" #include "SkColorPriv.h" #include "SkData.h" -#include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "SkMovie.h" #include "SkStream.h" @@ -29,210 +28,6 @@ #include <MobileCoreServices/MobileCoreServices.h> #endif -static void data_unref_proc(void* skdata, const void*, size_t) { - SkASSERT(skdata); - static_cast<SkData*>(skdata)->unref(); -} - -static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) { - // TODO: use callbacks, so we don't have to load all the data into RAM - SkData* skdata = SkCopyStreamToData(stream).release(); - if (!skdata) { - return nullptr; - } - - return CGDataProviderCreateWithData(skdata, skdata->data(), skdata->size(), data_unref_proc); -} - -static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) { - CGDataProviderRef data = SkStreamToDataProvider(stream); - if (!data) { - return nullptr; - } - CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0); - CGDataProviderRelease(data); - return imageSrc; -} - -class SkImageDecoder_CG : public SkImageDecoder { -protected: - virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode); -}; - -static void argb_4444_force_opaque(void* row, int count) { - uint16_t* row16 = (uint16_t*)row; - for (int i = 0; i < count; ++i) { - row16[i] |= 0xF000; - } -} - -static void argb_8888_force_opaque(void* row, int count) { - // can use RGBA or BGRA, they have the same shift for alpha - const uint32_t alphaMask = 0xFF << SK_RGBA_A32_SHIFT; - uint32_t* row32 = (uint32_t*)row; - for (int i = 0; i < count; ++i) { - row32[i] |= alphaMask; - } -} - -static void alpha_8_force_opaque(void* row, int count) { - memset(row, 0xFF, count); -} - -static void force_opaque(SkBitmap* bm) { - SkAutoLockPixels alp(*bm); - if (!bm->getPixels()) { - return; - } - - void (*proc)(void*, int); - switch (bm->colorType()) { - case kARGB_4444_SkColorType: - proc = argb_4444_force_opaque; - break; - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - proc = argb_8888_force_opaque; - break; - case kAlpha_8_SkColorType: - proc = alpha_8_force_opaque; - break; - default: - return; - } - - char* row = (char*)bm->getPixels(); - for (int y = 0; y < bm->height(); ++y) { - proc(row, bm->width()); - row += bm->rowBytes(); - } - bm->setAlphaType(kOpaque_SkAlphaType); -} - -#define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) - -class AutoCFDataRelease { - CFDataRef fDR; -public: - AutoCFDataRelease(CFDataRef dr) : fDR(dr) {} - ~AutoCFDataRelease() { if (fDR) { CFRelease(fDR); } } - - operator CFDataRef () { return fDR; } -}; - -static bool colorspace_is_sRGB(CGColorSpaceRef cs) { -#ifdef SK_BUILD_FOR_IOS - return true; // iOS seems to define itself to always return sRGB <reed> -#else - AutoCFDataRelease data(CGColorSpaceCopyICCProfile(cs)); - if (data) { - // found by inspection -- need a cleaner way to sniff a profile - const CFIndex ICC_PROFILE_OFFSET_TO_SRGB_TAG = 52; - - if (CFDataGetLength(data) >= ICC_PROFILE_OFFSET_TO_SRGB_TAG + 4) { - return !memcmp(CFDataGetBytePtr(data) + ICC_PROFILE_OFFSET_TO_SRGB_TAG, "sRGB", 4); - } - } - return false; -#endif -} - -SkImageDecoder::Result SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { - CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); - - if (nullptr == imageSrc) { - return kFailure; - } - SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); - - CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, nullptr); - if (nullptr == image) { - return kFailure; - } - SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); - - const int width = SkToInt(CGImageGetWidth(image)); - const int height = SkToInt(CGImageGetHeight(image)); - SkColorProfileType cpType = kLinear_SkColorProfileType; - - CGColorSpaceRef cs = CGImageGetColorSpace(image); - if (cs) { - CGColorSpaceModel m = CGColorSpaceGetModel(cs); - if (kCGColorSpaceModelRGB == m && colorspace_is_sRGB(cs)) { - cpType = kSRGB_SkColorProfileType; - } - } - - SkAlphaType at = kPremul_SkAlphaType; - switch (CGImageGetAlphaInfo(image)) { - case kCGImageAlphaNone: - case kCGImageAlphaNoneSkipLast: - case kCGImageAlphaNoneSkipFirst: - at = kOpaque_SkAlphaType; - break; - default: - break; - } - - bm->setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, at, cpType)); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { - return kSuccess; - } - - if (!this->allocPixelRef(bm, nullptr)) { - return kFailure; - } - - SkAutoLockPixels alp(*bm); - - if (!SkCopyPixelsFromCGImage(bm->info(), bm->rowBytes(), bm->getPixels(), image)) { - return kFailure; - } - - CGImageAlphaInfo info = CGImageGetAlphaInfo(image); - switch (info) { - case kCGImageAlphaNone: - case kCGImageAlphaNoneSkipLast: - case kCGImageAlphaNoneSkipFirst: - // We're opaque, but we can't rely on the data always having 0xFF - // in the alpha slot (which Skia wants), so we have to ram it in - // ourselves. - force_opaque(bm); - break; - default: - // we don't know if we're opaque or not, so compute it. - if (SkBitmap::ComputeIsOpaque(*bm)) { - bm->setAlphaType(kOpaque_SkAlphaType); - } - } - if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) { - // CGBitmapContext does not support unpremultiplied, so the image has been premultiplied. - // Convert to unpremultiplied. - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { - uint32_t* addr = bm->getAddr32(i, j); - *addr = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*addr); - } - } - bm->setAlphaType(kUnpremul_SkAlphaType); - } - return kSuccess; -} - -/////////////////////////////////////////////////////////////////////////////// - -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_CG. - return new SkImageDecoder_CG; - } else { - return decoder; - } -} - ///////////////////////////////////////////////////////////////////////// SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) { @@ -366,46 +161,4 @@ public: DEFINE_ENCODER_CREATOR(PNGImageEncoder_IOS); #endif -struct FormatConversion { - CFStringRef fUTType; - SkImageDecoder::Format fFormat; -}; - -// Array of the types supported by the decoder. -static const FormatConversion gFormatConversions[] = { - { kUTTypeBMP, SkImageDecoder::kBMP_Format }, - { kUTTypeGIF, SkImageDecoder::kGIF_Format }, - { kUTTypeICO, SkImageDecoder::kICO_Format }, - { kUTTypeJPEG, SkImageDecoder::kJPEG_Format }, - // Also include JPEG2000 - { kUTTypeJPEG2000, SkImageDecoder::kJPEG_Format }, - { kUTTypePNG, SkImageDecoder::kPNG_Format }, -}; - -static SkImageDecoder::Format UTType_to_Format(const CFStringRef uttype) { - for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) { - if (CFStringCompare(uttype, gFormatConversions[i].fUTType, 0) == kCFCompareEqualTo) { - return gFormatConversions[i].fFormat; - } - } - return SkImageDecoder::kUnknown_Format; -} - -static SkImageDecoder::Format get_format_cg(SkStreamRewindable* stream) { - CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); - - if (nullptr == imageSrc) { - return SkImageDecoder::kUnknown_Format; - } - - SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); - const CFStringRef name = CGImageSourceGetType(imageSrc); - if (nullptr == name) { - return SkImageDecoder::kUnknown_Format; - } - return UTType_to_Format(name); -} - -static SkImageDecoder_FormatReg gFormatReg(get_format_cg); - #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) diff --git a/src/ports/SkImageDecoder_WIC.cpp b/src/ports/SkImageDecoder_WIC.cpp index 5febd856d6..2d0e37c97b 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) { @@ -454,15 +237,4 @@ 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); - #endif // defined(SK_BUILD_FOR_WIN32) diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp index f52dada73b..33e07acea6 100644 --- a/src/ports/SkImageDecoder_empty.cpp +++ b/src/ports/SkImageDecoder_empty.cpp @@ -8,74 +8,11 @@ #include "SkBitmap.h" #include "SkImage.h" -#include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "SkMovie.h" #include "SkPixelSerializer.h" #include "SkStream.h" -class SkColorTable; -class SkPngChunkReader; - -// Empty implementations for SkImageDecoder. - -SkImageDecoder::SkImageDecoder() {} - -SkImageDecoder::~SkImageDecoder() {} - -SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable*) { - return nullptr; -} - -void SkImageDecoder::copyFieldsToOther(SkImageDecoder* ) {} - -bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkColorType, Mode, Format*) { - return false; -} - -SkImageDecoder::Result SkImageDecoder::decode(SkStream*, SkBitmap*, SkColorType, Mode) { - return kFailure; -} - -bool SkImageDecoder::DecodeStream(SkStreamRewindable*, SkBitmap*, SkColorType, Mode, Format*) { - return false; -} - -bool SkImageDecoder::DecodeMemory(const void*, size_t, SkBitmap*, SkColorType, Mode, Format*) { - return false; -} - -bool SkImageDecoder::decodeYUV8Planes(SkStream*, SkISize[3], void*[3], - size_t[3], SkYUVColorSpace*) { - return false; -} - -SkImageDecoder::Format SkImageDecoder::getFormat() const { - return kUnknown_Format; -} - -SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable*) { - return kUnknown_Format; -} - -const char* SkImageDecoder::GetFormatName(Format) { - return nullptr; -} - -SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader*) { - return nullptr; -} - -SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator*) { - return nullptr; -} - -void SkImageDecoder::setSampleSize(int) {} - -bool SkImageDecoder::allocPixelRef(SkBitmap*, SkColorTable*) const { - return false; -} - ///////////////////////////////////////////////////////////////////////// // Empty implementation for SkMovie. |