1
#include "SkImageRef.h"
3
#include "SkFlattenable.h"
4
#include "SkImageDecoder.h"
6
#include "SkTemplates.h"
9
// can't be static, as SkImageRef_Pool needs to see it
10
SkMutex gImageRefMutex;
12
///////////////////////////////////////////////////////////////////////////////
14
SkImageRef::SkImageRef(SkStream* stream, SkBitmap::Config config,
16
: SkPixelRef(&gImageRefMutex), fErrorInDecoding(false) {
18
SkASSERT(1 == stream->getRefCnt());
22
fSampleSize = sampleSize;
25
#ifdef DUMP_IMAGEREF_LIFECYCLE
26
SkDebugf("add ImageRef %p [%d] data=%d\n",
27
this, config, (int)stream->getLength());
31
SkImageRef::~SkImageRef() {
32
SkASSERT(&gImageRefMutex == this->mutex());
34
#ifdef DUMP_IMAGEREF_LIFECYCLE
35
SkDebugf("delete ImageRef %p [%d] data=%d\n",
36
this, fConfig, (int)fStream->getLength());
42
bool SkImageRef::getInfo(SkBitmap* bitmap) {
43
SkAutoMutexAcquire ac(gImageRefMutex);
45
if (!this->prepareBitmap(SkImageDecoder::kDecodeBounds_Mode)) {
49
SkASSERT(SkBitmap::kNo_Config != fBitmap.config());
51
bitmap->setConfig(fBitmap.config(), fBitmap.width(), fBitmap.height());
56
///////////////////////////////////////////////////////////////////////////////
58
bool SkImageRef::onDecode(SkImageDecoder* codec, SkStream* stream,
59
SkBitmap* bitmap, SkBitmap::Config config,
60
SkImageDecoder::Mode mode) {
61
return codec->decode(stream, bitmap, config, mode);
64
bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
65
SkASSERT(&gImageRefMutex == this->mutex());
67
if (fErrorInDecoding) {
71
/* As soon as we really know our config, we record it, so that on
72
subsequent calls to the codec, we are sure we will always get the same
75
if (SkBitmap::kNo_Config != fBitmap.config()) {
76
fConfig = fBitmap.config();
79
if (NULL != fBitmap.getPixels() ||
80
(SkBitmap::kNo_Config != fBitmap.config() &&
81
SkImageDecoder::kDecodeBounds_Mode == mode)) {
85
SkASSERT(fBitmap.getPixels() == NULL);
89
SkImageDecoder* codec = SkImageDecoder::Factory(fStream);
91
SkAutoTDelete<SkImageDecoder> ad(codec);
93
codec->setSampleSize(fSampleSize);
94
if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) {
99
#ifdef DUMP_IMAGEREF_LIFECYCLE
101
SkDebugf("--- ImageRef: <%s> failed to find codec\n", this->getURI());
103
SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n",
104
this->getURI(), mode);
107
fErrorInDecoding = true;
112
void* SkImageRef::onLockPixels(SkColorTable** ct) {
113
SkASSERT(&gImageRefMutex == this->mutex());
115
if (NULL == fBitmap.getPixels()) {
116
(void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode);
120
*ct = fBitmap.getColorTable();
122
return fBitmap.getPixels();
125
void SkImageRef::onUnlockPixels() {
126
// we're already have the mutex locked
127
SkASSERT(&gImageRefMutex == this->mutex());
130
size_t SkImageRef::ramUsed() const {
133
if (fBitmap.getPixels()) {
134
size = fBitmap.getSize();
135
if (fBitmap.getColorTable()) {
136
size += fBitmap.getColorTable()->count() * sizeof(SkPMColor);
142
///////////////////////////////////////////////////////////////////////////////
144
SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer)
145
: INHERITED(buffer, &gImageRefMutex), fErrorInDecoding(false) {
146
fConfig = (SkBitmap::Config)buffer.readU8();
147
fSampleSize = buffer.readU8();
148
size_t length = buffer.readU32();
149
fStream = SkNEW_ARGS(SkMemoryStream, (length));
150
buffer.read((void*)fStream->getMemoryBase(), length);
152
fPrev = fNext = NULL;
155
void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const {
156
this->INHERITED::flatten(buffer);
158
buffer.write8(fConfig);
159
buffer.write8(fSampleSize);
160
size_t length = fStream->getLength();
161
buffer.write32(length);
163
buffer.readFromStream(fStream, length);