OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkImagePriv.h" | 11 #include "SkImagePriv.h" |
12 #include "SkPixelRef.h" | 12 #include "SkPixelRef.h" |
13 #include "SkStream.h" | 13 #include "SkStream.h" |
14 #include "SkTemplates.h" | 14 #include "SkTemplates.h" |
| 15 #include "SkCanvas.h" |
15 | 16 |
16 SK_DEFINE_INST_COUNT(SkImageDecoder::Peeker) | 17 SK_DEFINE_INST_COUNT(SkImageDecoder::Peeker) |
17 SK_DEFINE_INST_COUNT(SkImageDecoder::Chooser) | 18 SK_DEFINE_INST_COUNT(SkImageDecoder::Chooser) |
18 SK_DEFINE_INST_COUNT(SkImageDecoderFactory) | 19 SK_DEFINE_INST_COUNT(SkImageDecoderFactory) |
19 | 20 |
| 21 const char *SkImageDecoder::sFormatName[] = { |
| 22 "Unknown Format", |
| 23 "BMP", |
| 24 "GIF", |
| 25 "ICO", |
| 26 "JPEG", |
| 27 "PNG", |
| 28 "WBMP", |
| 29 "WEBP", |
| 30 }; |
| 31 |
20 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; | 32 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; |
21 | 33 |
22 SkBitmap::Config SkImageDecoder::GetDeviceConfig() | 34 SkBitmap::Config SkImageDecoder::GetDeviceConfig() |
23 { | 35 { |
24 return gDeviceConfig; | 36 return gDeviceConfig; |
25 } | 37 } |
26 | 38 |
27 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) | 39 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) |
28 { | 40 { |
29 gDeviceConfig = config; | 41 gDeviceConfig = config; |
30 } | 42 } |
31 | 43 |
32 /////////////////////////////////////////////////////////////////////////////// | 44 /////////////////////////////////////////////////////////////////////////////// |
33 | 45 |
34 SkImageDecoder::SkImageDecoder() | 46 SkImageDecoder::SkImageDecoder() |
35 : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), | 47 : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), |
36 fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), | 48 fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), |
37 fUsePrefTable(false) { | 49 fUsePrefTable(false),fPreferQualityOverSpeed(false) { |
38 } | 50 } |
39 | 51 |
40 SkImageDecoder::~SkImageDecoder() { | 52 SkImageDecoder::~SkImageDecoder() { |
41 SkSafeUnref(fPeeker); | 53 SkSafeUnref(fPeeker); |
42 SkSafeUnref(fChooser); | 54 SkSafeUnref(fChooser); |
43 SkSafeUnref(fAllocator); | 55 SkSafeUnref(fAllocator); |
44 } | 56 } |
45 | 57 |
46 SkImageDecoder::Format SkImageDecoder::getFormat() const { | 58 SkImageDecoder::Format SkImageDecoder::getFormat() const { |
47 return kUnknown_Format; | 59 return kUnknown_Format; |
48 } | 60 } |
49 | 61 |
| 62 const char* SkImageDecoder::getFormatName() const { |
| 63 SkASSERT(SK_ARRAY_COUNT(sFormatName) == kLastKnownFormat); |
| 64 return sFormatName[this->getFormat()]; |
| 65 } |
| 66 |
50 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { | 67 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { |
51 SkRefCnt_SafeAssign(fPeeker, peeker); | 68 SkRefCnt_SafeAssign(fPeeker, peeker); |
52 return peeker; | 69 return peeker; |
53 } | 70 } |
54 | 71 |
55 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { | 72 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { |
56 SkRefCnt_SafeAssign(fChooser, chooser); | 73 SkRefCnt_SafeAssign(fChooser, chooser); |
57 return chooser; | 74 return chooser; |
58 } | 75 } |
59 | 76 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 config = fDefaultPref; | 139 config = fDefaultPref; |
123 } | 140 } |
124 | 141 |
125 if (SkBitmap::kNo_Config == config) { | 142 if (SkBitmap::kNo_Config == config) { |
126 config = SkImageDecoder::GetDeviceConfig(); | 143 config = SkImageDecoder::GetDeviceConfig(); |
127 } | 144 } |
128 return config; | 145 return config; |
129 } | 146 } |
130 | 147 |
131 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, | 148 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, |
132 SkBitmap::Config pref, Mode mode) { | 149 SkBitmap::Config pref, Mode mode, bool reuseBitmap)
{ |
133 // pass a temporary bitmap, so that if we return false, we are assured of | |
134 // leaving the caller's bitmap untouched. | |
135 SkBitmap tmp; | |
136 | |
137 // we reset this to false before calling onDecode | 150 // we reset this to false before calling onDecode |
138 fShouldCancelDecode = false; | 151 fShouldCancelDecode = false; |
139 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false | 152 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
140 fDefaultPref = pref; | 153 fDefaultPref = pref; |
141 | 154 |
| 155 if (reuseBitmap) { |
| 156 SkAutoLockPixels alp(*bm); |
| 157 if (NULL != bm->getPixels()) { |
| 158 return this->onDecode(stream, bm, mode); |
| 159 } |
| 160 } |
| 161 |
| 162 // pass a temporary bitmap, so that if we return false, we are assured of |
| 163 // leaving the caller's bitmap untouched. |
| 164 SkBitmap tmp; |
142 if (!this->onDecode(stream, &tmp, mode)) { | 165 if (!this->onDecode(stream, &tmp, mode)) { |
143 return false; | 166 return false; |
144 } | 167 } |
145 bm->swap(tmp); | 168 bm->swap(tmp); |
146 return true; | 169 return true; |
147 } | 170 } |
148 | 171 |
| 172 bool SkImageDecoder::decodeRegion(SkBitmap* bm, const SkIRect& rect, |
| 173 SkBitmap::Config pref) { |
| 174 // we reset this to false before calling onDecodeRegion |
| 175 fShouldCancelDecode = false; |
| 176 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
| 177 fDefaultPref = pref; |
| 178 |
| 179 return this->onDecodeRegion(bm, rect); |
| 180 } |
| 181 |
| 182 bool SkImageDecoder::buildTileIndex(SkStream* stream, |
| 183 int *width, int *height) { |
| 184 // we reset this to false before calling onBuildTileIndex |
| 185 fShouldCancelDecode = false; |
| 186 |
| 187 return this->onBuildTileIndex(stream, width, height); |
| 188 } |
| 189 |
| 190 void SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
| 191 int dstX, int dstY, int width, int height, |
| 192 int srcX, int srcY) { |
| 193 int w = width / sampleSize; |
| 194 int h = height / sampleSize; |
| 195 // if the destination has no pixels then we must allocate them. |
| 196 if (dst->isNull()) { |
| 197 dst->setConfig(src->getConfig(), w, h); |
| 198 dst->setIsOpaque(src->isOpaque()); |
| 199 |
| 200 if (!this->allocPixelRef(dst, NULL)) { |
| 201 SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); |
| 202 return; |
| 203 } |
| 204 } |
| 205 // check to see if the destination is large enough to decode the desired |
| 206 // region. If this assert fails we will just draw as much of the source |
| 207 // into the destination that we can. |
| 208 SkASSERT(dst->width() >= w && dst->height() >= h); |
| 209 |
| 210 // Set the Src_Mode for the paint to prevent transparency issue in the |
| 211 // dest in the event that the dest was being re-used. |
| 212 SkPaint paint; |
| 213 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 214 |
| 215 SkCanvas canvas(*dst); |
| 216 canvas.drawSprite(*src, (srcX - dstX) / sampleSize, |
| 217 (srcY - dstY) / sampleSize, |
| 218 &paint); |
| 219 } |
| 220 |
149 /////////////////////////////////////////////////////////////////////////////// | 221 /////////////////////////////////////////////////////////////////////////////// |
150 | 222 |
151 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, | 223 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, |
152 SkBitmap::Config pref, Mode mode, Format* format) { | 224 SkBitmap::Config pref, Mode mode, Format* format) { |
153 SkASSERT(file); | 225 SkASSERT(file); |
154 SkASSERT(bm); | 226 SkASSERT(bm); |
155 | 227 |
156 SkFILEStream stream(file); | 228 SkFILEStream stream(file); |
157 if (stream.isValid()) { | 229 if (stream.isValid()) { |
158 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { | 230 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 319 |
248 if (NULL != codec) { | 320 if (NULL != codec) { |
249 success = codec->decode(stream, bm, pref, mode); | 321 success = codec->decode(stream, bm, pref, mode); |
250 if (success && format) { | 322 if (success && format) { |
251 *format = codec->getFormat(); | 323 *format = codec->getFormat(); |
252 } | 324 } |
253 delete codec; | 325 delete codec; |
254 } | 326 } |
255 return success; | 327 return success; |
256 } | 328 } |
OLD | NEW |