OLD | NEW |
| (Empty) |
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", fName.c_str()); | |
102 } else { | |
103 SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n", | |
104 fName.c_str(), 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 | |
OLD | NEW |