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); |
+} |