Chromium Code Reviews| Index: src/images/SkImageDecoder_pkm.cpp |
| diff --git a/src/images/SkImageDecoder_pkm.cpp b/src/images/SkImageDecoder_pkm.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8fe1addb3cc039b5d71848d8da1129c9090b0ec5 |
| --- /dev/null |
| +++ b/src/images/SkImageDecoder_pkm.cpp |
| @@ -0,0 +1,135 @@ |
| +/* |
|
robertphillips
2014/05/22 14:41:35
Please use new header (not Android one).
krajcevski
2014/05/22 15:32:17
Done.
|
| + * 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 "SkColorPriv.h" |
| +#include "SkImageDecoder.h" |
| +#include "SkStream.h" |
| +#include "SkStreamHelpers.h" |
| +#include "SkTypes.h" |
| + |
| +#include "etc1.h" |
| + |
| +class SkPKMImageDecoder : public SkImageDecoder { |
| +public: |
| + SkPKMImageDecoder(); |
| + |
| + virtual Format getFormat() const SK_OVERRIDE { |
| + return kPKM_Format; |
| + } |
| + |
| +protected: |
| + virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; |
| + |
| +private: |
| + typedef SkImageDecoder INHERITED; |
| +}; |
| + |
| +///////////////////////////////////////////////////////////////////////////////////////// |
| + |
|
robertphillips
2014/05/22 14:41:35
Put this in the class?
krajcevski
2014/05/22 15:32:17
Done.
|
| +SkPKMImageDecoder::SkPKMImageDecoder() |
| +{ |
| +} |
| + |
| +bool SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) |
| +{ |
| + SkAutoMalloc autoMal; |
| + const size_t length = CopyStreamToStorage(&autoMal, stream); |
| + if (0 == length) { |
| + return false; |
| + } |
| + |
| + unsigned char* buf = (unsigned char*)autoMal.get(); |
| + |
| + // Make sure original PKM header is there... |
| + SkASSERT(etc1_pkm_is_valid(buf)); |
| + |
| + const unsigned short width = etc1_pkm_get_width(buf); |
| + const unsigned short height = etc1_pkm_get_height(buf); |
| + |
| + // should we allow the Chooser (if present) to pick a config for us??? |
| + if (!this->chooseFromOneChoice(SkBitmap::kARGB_8888_Config, |
| + width, height) |
|
robertphillips
2014/05/22 14:41:35
Move the ") {" to the prior line?
Can it all fit o
krajcevski
2014/05/22 15:32:17
Done.
|
| + ) { |
| + return false; |
| + } |
| + |
|
robertphillips
2014/05/22 14:41:35
one 100 col line?
krajcevski
2014/05/22 15:32:17
Done.
|
| + bm->setConfig(SkBitmap::kARGB_8888_Config, width, height, 0, |
| + kOpaque_SkAlphaType); |
| + if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| + return true; |
| + } |
| + |
| + if (!this->allocPixelRef(bm, NULL)) { |
| + return false; |
| + } |
| + |
| + // Lock the pixels, since we're about to write to them... |
| + SkAutoLockPixels alp(*bm); |
| + |
| + // Advance buffer past the header |
| + buf += ETC_PKM_HEADER_SIZE; |
| + |
| + // ETC1 Data is encoded as RGB pixels, so we should extract it as such |
| + int nPixels = width * height; |
| + SkAutoMalloc outRGBData(nPixels * 3); |
| + etc1_byte *outRGBDataPtr = reinterpret_cast<etc1_byte *>(outRGBData.get()); |
| + |
| + // Decode ETC1 |
|
robertphillips
2014/05/22 14:41:35
space after if?
krajcevski
2014/05/22 15:32:17
Done.
|
| + if(etc1_decode_image(buf, outRGBDataPtr, width, height, 3, width*3)) { |
| + return false; |
| + } |
| + |
| + // Set each of the pixels... |
| + const uint8_t *src = reinterpret_cast<uint8_t *>(outRGBDataPtr); |
| + uint8_t *dst = reinterpret_cast<uint8_t *>(bm->getPixels()); |
|
robertphillips
2014/05/22 14:41:35
++i ?
krajcevski
2014/05/22 15:32:17
Done.
|
| + for(int i = 0; i < width*height; i++) { |
| + *dst++ = src[2]; // B |
| + *dst++ = src[1]; // G |
| + *dst++ = src[0]; // R |
| + *dst++ = 0xFF; // Opaque alpha... |
| + src += 3; |
| + } |
| + |
| + return true; |
|
robertphillips
2014/05/22 14:41:35
rm "//onDecode" ? Not really standard.
krajcevski
2014/05/22 15:32:17
Done.
|
| +} //onDecode |
| + |
|
robertphillips
2014/05/22 14:41:35
Why are the "///*" lines different length. I think
krajcevski
2014/05/22 15:32:17
Done.
|
| +/////////////////////////////////////////////////////////////////////////////// |
| +DEFINE_DECODER_CREATOR(PKMImageDecoder); |
| +///////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +static bool is_pkm(SkStreamRewindable* stream) { |
|
robertphillips
2014/05/22 14:41:35
are ... ?
krajcevski
2014/05/22 15:32:17
Done.
|
| + // Check to see if the first four bytes are |
|
robertphillips
2014/05/22 14:41:35
Do we really need an AutoMalloc for 6 bytes? Can w
krajcevski
2014/05/22 15:32:17
Done.
|
| + SkAutoMalloc autoMal(6); |
| + unsigned char* buf = (unsigned char*)autoMal.get(); |
|
robertphillips
2014/05/22 14:41:35
space after if ?
krajcevski
2014/05/22 15:32:17
Done.
|
| + if(stream->read((void*)buf, ETC_PKM_HEADER_SIZE) != ETC_PKM_HEADER_SIZE) { |
| + return false; |
| + } |
| + |
|
robertphillips
2014/05/22 14:41:35
return etc1_pkm_is_valid(buf); ?
krajcevski
2014/05/22 15:32:17
Done.
|
| + if (etc1_pkm_is_valid(buf)) { |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| +static SkImageDecoder* sk_libpkm_dfactory(SkStreamRewindable* stream) { |
| + if (is_pkm(stream)) { |
| + return SkNEW(SkPKMImageDecoder); |
| + } |
| + return NULL; |
| +} |
| + |
| +static SkImageDecoder_DecodeReg gReg(sk_libpkm_dfactory); |
| + |
| +static SkImageDecoder::Format get_format_pkm(SkStreamRewindable* stream) { |
| + if (is_pkm(stream)) { |
| + return SkImageDecoder::kPKM_Format; |
| + } |
| + return SkImageDecoder::kUnknown_Format; |
| +} |
| + |
| +static SkImageDecoder_FormatReg gFormatReg(get_format_pkm); |