diff options
author | 2016-03-23 18:52:40 -0700 | |
---|---|---|
committer | 2016-03-23 18:52:40 -0700 | |
commit | 041c870425eb0a3e2b0cbc46581b3da2f50571d9 (patch) | |
tree | 9ae4beff0b55afbe7cb6471b561ac309c80b2244 /src/images/SkImageDecoder_libbmp.cpp | |
parent | 5b6e73e0c8282c4d85accbfbcecc6dee84f8a1eb (diff) |
Revert of Delete SkImageDecoder (patchset #8 id:130001 of https://codereview.chromium.org/1820503002/ )
Reason for revert:
Testing the roll - it's still failing
Original issue's description:
> Delete SkImageDecoder
>
> This image decoding implementation has been replaced
> by SkCodec in Android.
>
> Additionally, we have replaced uses of SkImageDecoder
> in Skia and Google3 with uses of SkCodec.
>
> Now we can delete SkImageDecoder :).
>
> BUG=skia:
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1820503002
> CQ_EXTRA_TRYBOTS=client.skia.compile:Build-Ubuntu-GCC-x86_64-Release-CMake-Trybot,Build-Mac-Clang-x86_64-Release-CMake-Trybot
>
> Committed: https://skia.googlesource.com/skia/+/f799706656f2581c5bf5510d94df3fa17cce1607
>
> Committed: https://skia.googlesource.com/skia/+/5b6e73e0c8282c4d85accbfbcecc6dee84f8a1eb
TBR=scroggo@google.com,djsollen@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/1828433004
Diffstat (limited to 'src/images/SkImageDecoder_libbmp.cpp')
-rw-r--r-- | src/images/SkImageDecoder_libbmp.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp new file mode 100644 index 0000000000..b9359bea7a --- /dev/null +++ b/src/images/SkImageDecoder_libbmp.cpp @@ -0,0 +1,166 @@ + +/* + * Copyright 2007 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 "bmpdecoderhelper.h" +#include "SkColorPriv.h" +#include "SkData.h" +#include "SkImageDecoder.h" +#include "SkScaledBitmapSampler.h" +#include "SkStream.h" +#include "SkStreamPriv.h" +#include "SkTDArray.h" + +class SkBMPImageDecoder : public SkImageDecoder { +public: + SkBMPImageDecoder() {} + + Format getFormat() const override { + return kBMP_Format; + } + +protected: + Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override; + +private: + typedef SkImageDecoder INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// +DEFINE_DECODER_CREATOR(BMPImageDecoder); +/////////////////////////////////////////////////////////////////////////////// + +static bool is_bmp(SkStreamRewindable* stream) { + static const char kBmpMagic[] = { 'B', 'M' }; + + + char buffer[sizeof(kBmpMagic)]; + + return stream->read(buffer, sizeof(kBmpMagic)) == sizeof(kBmpMagic) && + !memcmp(buffer, kBmpMagic, sizeof(kBmpMagic)); +} + +static SkImageDecoder* sk_libbmp_dfactory(SkStreamRewindable* stream) { + if (is_bmp(stream)) { + return new SkBMPImageDecoder; + } + return nullptr; +} + +static SkImageDecoder_DecodeReg gReg(sk_libbmp_dfactory); + +static SkImageDecoder::Format get_format_bmp(SkStreamRewindable* stream) { + if (is_bmp(stream)) { + return SkImageDecoder::kBMP_Format; + } + return SkImageDecoder::kUnknown_Format; +} + +static SkImageDecoder_FormatReg gFormatReg(get_format_bmp); + +/////////////////////////////////////////////////////////////////////////////// + +class SkBmpDecoderCallback : public image_codec::BmpDecoderCallback { +public: + // we don't copy the bitmap, just remember the pointer + SkBmpDecoderCallback(bool justBounds) : fJustBounds(justBounds) {} + + // override from BmpDecoderCallback + virtual uint8* SetSize(int width, int height) { + fWidth = width; + fHeight = height; + if (fJustBounds) { + return nullptr; + } + + fRGB.setCount(width * height * 3); // 3 == r, g, b + return fRGB.begin(); + } + + int width() const { return fWidth; } + int height() const { return fHeight; } + const uint8_t* rgb() const { return fRGB.begin(); } + +private: + SkTDArray<uint8_t> fRGB; + int fWidth; + int fHeight; + bool fJustBounds; +}; + +SkImageDecoder::Result SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { + // First read the entire stream, so that all of the data can be passed to + // the BmpDecoderHelper. + + auto data = SkCopyStreamToData(stream); + if (!data) { + return kFailure; + } + + // Byte length of all of the data. + const size_t length = data->size(); + if (0 == length) { + return kFailure; + } + + const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode; + SkBmpDecoderCallback callback(justBounds); + + // Now decode the BMP into callback's rgb() array [r,g,b, r,g,b, ...] + { + image_codec::BmpDecoderHelper helper; + const int max_pixels = 16383*16383; // max width*height + if (!helper.DecodeImage((const char*) data->data(), length, + max_pixels, &callback)) { + return kFailure; + } + } + + // we don't need this anymore, so free it now (before we try to allocate + // the bitmap's pixels) rather than waiting for its destructor + data.reset(nullptr); + + int width = callback.width(); + int height = callback.height(); + SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, false); + + // only accept prefConfig if it makes sense for us + if (kARGB_4444_SkColorType != colorType && kRGB_565_SkColorType != colorType) { + colorType = kN32_SkColorType; + } + + SkScaledBitmapSampler sampler(width, height, getSampleSize()); + + bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(), + colorType, kOpaque_SkAlphaType)); + + if (justBounds) { + return kSuccess; + } + + if (!this->allocPixelRef(bm, nullptr)) { + return kFailure; + } + + SkAutoLockPixels alp(*bm); + + if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { + return kFailure; + } + + const int srcRowBytes = width * 3; + const int dstHeight = sampler.scaledHeight(); + const uint8_t* srcRow = callback.rgb(); + + srcRow += sampler.srcY0() * srcRowBytes; + for (int y = 0; y < dstHeight; y++) { + sampler.next(srcRow); + srcRow += sampler.srcDY() * srcRowBytes; + } + return kSuccess; +} |