| Index: src/images/SkImageDecoder.cpp
|
| diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..221faf74d5e33cf0160e765c3887c69a7e7b3a45
|
| --- /dev/null
|
| +++ b/src/images/SkImageDecoder.cpp
|
| @@ -0,0 +1,204 @@
|
| +/*
|
| + * Copyright 2006 The Android Open Source Project
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +
|
| +#include "SkImageDecoder.h"
|
| +#include "SkBitmap.h"
|
| +#include "SkImagePriv.h"
|
| +#include "SkPixelRef.h"
|
| +#include "SkStream.h"
|
| +#include "SkTemplates.h"
|
| +#include "SkCanvas.h"
|
| +
|
| +SkImageDecoder::SkImageDecoder()
|
| + : fPeeker(nullptr)
|
| + , fAllocator(nullptr)
|
| + , fSampleSize(1)
|
| + , fDefaultPref(kUnknown_SkColorType)
|
| + , fPreserveSrcDepth(false)
|
| + , fDitherImage(true)
|
| + , fSkipWritingZeroes(false)
|
| + , fPreferQualityOverSpeed(false)
|
| + , fRequireUnpremultipliedColors(false) {
|
| +}
|
| +
|
| +SkImageDecoder::~SkImageDecoder() {
|
| + SkSafeUnref(fPeeker);
|
| + SkSafeUnref(fAllocator);
|
| +}
|
| +
|
| +void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
|
| + if (nullptr == other) {
|
| + return;
|
| + }
|
| + other->setPeeker(fPeeker);
|
| + other->setAllocator(fAllocator);
|
| + other->setSampleSize(fSampleSize);
|
| + other->setPreserveSrcDepth(fPreserveSrcDepth);
|
| + other->setDitherImage(fDitherImage);
|
| + other->setSkipWritingZeroes(fSkipWritingZeroes);
|
| + other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
|
| + other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
|
| +}
|
| +
|
| +SkImageDecoder::Format SkImageDecoder::getFormat() const {
|
| + return kUnknown_Format;
|
| +}
|
| +
|
| +const char* SkImageDecoder::getFormatName() const {
|
| + return GetFormatName(this->getFormat());
|
| +}
|
| +
|
| +const char* SkImageDecoder::GetFormatName(Format format) {
|
| + switch (format) {
|
| + case kUnknown_Format:
|
| + return "Unknown Format";
|
| + case kBMP_Format:
|
| + return "BMP";
|
| + case kGIF_Format:
|
| + return "GIF";
|
| + case kICO_Format:
|
| + return "ICO";
|
| + case kPKM_Format:
|
| + return "PKM";
|
| + case kKTX_Format:
|
| + return "KTX";
|
| + case kASTC_Format:
|
| + return "ASTC";
|
| + case kJPEG_Format:
|
| + return "JPEG";
|
| + case kPNG_Format:
|
| + return "PNG";
|
| + case kWBMP_Format:
|
| + return "WBMP";
|
| + case kWEBP_Format:
|
| + return "WEBP";
|
| + default:
|
| + SkDEBUGFAIL("Invalid format type!");
|
| + }
|
| + return "Unknown Format";
|
| +}
|
| +
|
| +SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader* peeker) {
|
| + SkRefCnt_SafeAssign(fPeeker, peeker);
|
| + return peeker;
|
| +}
|
| +
|
| +SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
|
| + SkRefCnt_SafeAssign(fAllocator, alloc);
|
| + return alloc;
|
| +}
|
| +
|
| +void SkImageDecoder::setSampleSize(int size) {
|
| + if (size < 1) {
|
| + size = 1;
|
| + }
|
| + fSampleSize = size;
|
| +}
|
| +
|
| +bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
|
| + SkColorTable* ctable) const {
|
| + return bitmap->tryAllocPixels(fAllocator, ctable);
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const {
|
| + SkColorType ct = fDefaultPref;
|
| + if (fPreserveSrcDepth) {
|
| + switch (srcDepth) {
|
| + case kIndex_SrcDepth:
|
| + ct = kIndex_8_SkColorType;
|
| + break;
|
| + case k8BitGray_SrcDepth:
|
| + ct = kN32_SkColorType;
|
| + break;
|
| + case k32Bit_SrcDepth:
|
| + ct = kN32_SkColorType;
|
| + break;
|
| + }
|
| + }
|
| + return ct;
|
| +}
|
| +
|
| +SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref,
|
| + Mode mode) {
|
| + // we reset this to false before calling onDecode
|
| + fShouldCancelDecode = false;
|
| + // assign this, for use by getPrefColorType(), in case fUsePrefTable is false
|
| + fDefaultPref = pref;
|
| +
|
| + // pass a temporary bitmap, so that if we return false, we are assured of
|
| + // leaving the caller's bitmap untouched.
|
| + SkBitmap tmp;
|
| + const Result result = this->onDecode(stream, &tmp, mode);
|
| + if (kFailure != result) {
|
| + bm->swap(tmp);
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pref, Mode mode,
|
| + Format* format) {
|
| + SkASSERT(file);
|
| + SkASSERT(bm);
|
| +
|
| + SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(file));
|
| + if (stream.get()) {
|
| + if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
|
| + if (SkPixelRef* pr = bm->pixelRef()) {
|
| + pr->setURI(file);
|
| + }
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, SkColorType pref,
|
| + Mode mode, Format* format) {
|
| + if (0 == size) {
|
| + return false;
|
| + }
|
| + SkASSERT(buffer);
|
| +
|
| + SkMemoryStream stream(buffer, size);
|
| + return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
|
| +}
|
| +
|
| +bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkColorType pref,
|
| + Mode mode, Format* format) {
|
| + SkASSERT(stream);
|
| + SkASSERT(bm);
|
| +
|
| + bool success = false;
|
| + SkImageDecoder* codec = SkImageDecoder::Factory(stream);
|
| +
|
| + if (codec) {
|
| + success = codec->decode(stream, bm, pref, mode) != kFailure;
|
| + if (success && format) {
|
| + *format = codec->getFormat();
|
| + if (kUnknown_Format == *format) {
|
| + if (stream->rewind()) {
|
| + *format = GetStreamFormat(stream);
|
| + }
|
| + }
|
| + }
|
| + delete codec;
|
| + }
|
| + return success;
|
| +}
|
| +
|
| +bool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
|
| + size_t rowBytes[3], SkYUVColorSpace* colorSpace) {
|
| + // we reset this to false before calling onDecodeYUV8Planes
|
| + fShouldCancelDecode = false;
|
| +
|
| + return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, colorSpace);
|
| +}
|
|
|