~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/skia/src/images/SkImageRef.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "SkImageRef.h"
 
2
#include "SkBitmap.h"
 
3
#include "SkFlattenable.h"
 
4
#include "SkImageDecoder.h"
 
5
#include "SkStream.h"
 
6
#include "SkTemplates.h"
 
7
#include "SkThread.h"
 
8
 
 
9
// can't be static, as SkImageRef_Pool needs to see it
 
10
SkMutex gImageRefMutex;
 
11
 
 
12
///////////////////////////////////////////////////////////////////////////////
 
13
 
 
14
SkImageRef::SkImageRef(SkStream* stream, SkBitmap::Config config,
 
15
                       int sampleSize)
 
16
        : SkPixelRef(&gImageRefMutex), fErrorInDecoding(false) {
 
17
    SkASSERT(stream);
 
18
    SkASSERT(1 == stream->getRefCnt());
 
19
 
 
20
    fStream = stream;
 
21
    fConfig = config;
 
22
    fSampleSize = sampleSize;
 
23
    fPrev = fNext = NULL;
 
24
 
 
25
#ifdef DUMP_IMAGEREF_LIFECYCLE
 
26
    SkDebugf("add ImageRef %p [%d] data=%d\n",
 
27
              this, config, (int)stream->getLength());
 
28
#endif
 
29
}
 
30
 
 
31
SkImageRef::~SkImageRef() {
 
32
    SkASSERT(&gImageRefMutex == this->mutex());
 
33
 
 
34
#ifdef DUMP_IMAGEREF_LIFECYCLE
 
35
    SkDebugf("delete ImageRef %p [%d] data=%d\n",
 
36
              this, fConfig, (int)fStream->getLength());
 
37
#endif
 
38
 
 
39
    delete fStream;
 
40
}
 
41
 
 
42
bool SkImageRef::getInfo(SkBitmap* bitmap) {
 
43
    SkAutoMutexAcquire ac(gImageRefMutex);
 
44
    
 
45
    if (!this->prepareBitmap(SkImageDecoder::kDecodeBounds_Mode)) {
 
46
        return false;
 
47
    }
 
48
    
 
49
    SkASSERT(SkBitmap::kNo_Config != fBitmap.config());
 
50
    if (bitmap) {
 
51
        bitmap->setConfig(fBitmap.config(), fBitmap.width(), fBitmap.height());
 
52
    }
 
53
    return true;
 
54
}
 
55
 
 
56
///////////////////////////////////////////////////////////////////////////////
 
57
 
 
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);
 
62
}
 
63
 
 
64
bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
 
65
    SkASSERT(&gImageRefMutex == this->mutex());
 
66
 
 
67
    if (fErrorInDecoding) {
 
68
        return false;
 
69
    }
 
70
    
 
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
 
73
        result.
 
74
    */
 
75
    if (SkBitmap::kNo_Config != fBitmap.config()) {
 
76
        fConfig = fBitmap.config();
 
77
    }
 
78
    
 
79
    if (NULL != fBitmap.getPixels() ||
 
80
            (SkBitmap::kNo_Config != fBitmap.config() &&
 
81
             SkImageDecoder::kDecodeBounds_Mode == mode)) {
 
82
        return true;
 
83
    }
 
84
 
 
85
    SkASSERT(fBitmap.getPixels() == NULL);
 
86
 
 
87
    fStream->rewind();
 
88
        
 
89
    SkImageDecoder* codec = SkImageDecoder::Factory(fStream);
 
90
    if (codec) {
 
91
        SkAutoTDelete<SkImageDecoder> ad(codec);
 
92
 
 
93
        codec->setSampleSize(fSampleSize);
 
94
        if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) {
 
95
            return true;
 
96
        }
 
97
    }
 
98
 
 
99
#ifdef DUMP_IMAGEREF_LIFECYCLE
 
100
    if (NULL == codec) {
 
101
        SkDebugf("--- ImageRef: <%s> failed to find codec\n", this->getURI());
 
102
    } else {
 
103
        SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n",
 
104
                 this->getURI(), mode);
 
105
    }
 
106
#endif
 
107
    fErrorInDecoding = true;
 
108
    fBitmap.reset();
 
109
    return false;
 
110
}
 
111
 
 
112
void* SkImageRef::onLockPixels(SkColorTable** ct) {
 
113
    SkASSERT(&gImageRefMutex == this->mutex());
 
114
 
 
115
    if (NULL == fBitmap.getPixels()) {
 
116
        (void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode);
 
117
    }
 
118
 
 
119
    if (ct) {
 
120
        *ct = fBitmap.getColorTable();
 
121
    }
 
122
    return fBitmap.getPixels();
 
123
}
 
124
 
 
125
void SkImageRef::onUnlockPixels() {
 
126
    // we're already have the mutex locked
 
127
    SkASSERT(&gImageRefMutex == this->mutex());
 
128
}
 
129
 
 
130
size_t SkImageRef::ramUsed() const {
 
131
    size_t size = 0;
 
132
 
 
133
    if (fBitmap.getPixels()) {
 
134
        size = fBitmap.getSize();
 
135
        if (fBitmap.getColorTable()) {
 
136
            size += fBitmap.getColorTable()->count() * sizeof(SkPMColor);
 
137
        }
 
138
    }
 
139
    return size;
 
140
}
 
141
 
 
142
///////////////////////////////////////////////////////////////////////////////
 
143
 
 
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);
 
151
 
 
152
    fPrev = fNext = NULL;
 
153
}
 
154
 
 
155
void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const {
 
156
    this->INHERITED::flatten(buffer);
 
157
 
 
158
    buffer.write8(fConfig);
 
159
    buffer.write8(fSampleSize);
 
160
    size_t length = fStream->getLength();
 
161
    buffer.write32(length);
 
162
    fStream->rewind();
 
163
    buffer.readFromStream(fStream, length);
 
164
}
 
165