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::kFormatName[] = { |
| 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; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 config = fDefaultPref; | 134 config = fDefaultPref; |
123 } | 135 } |
124 | 136 |
125 if (SkBitmap::kNo_Config == config) { | 137 if (SkBitmap::kNo_Config == config) { |
126 config = SkImageDecoder::GetDeviceConfig(); | 138 config = SkImageDecoder::GetDeviceConfig(); |
127 } | 139 } |
128 return config; | 140 return config; |
129 } | 141 } |
130 | 142 |
131 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, | 143 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, |
132 SkBitmap::Config pref, Mode mode) { | 144 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 | 145 // we reset this to false before calling onDecode |
138 fShouldCancelDecode = false; | 146 fShouldCancelDecode = false; |
139 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false | 147 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
140 fDefaultPref = pref; | 148 fDefaultPref = pref; |
141 | 149 |
| 150 if (reuseBitmap) { |
| 151 SkAutoLockPixels alp(*bm); |
| 152 if (NULL != bm->getPixels()) { |
| 153 return this->onDecode(stream, bm, mode); |
| 154 } |
| 155 } |
| 156 |
| 157 // pass a temporary bitmap, so that if we return false, we are assured of |
| 158 // leaving the caller's bitmap untouched. |
| 159 SkBitmap tmp; |
142 if (!this->onDecode(stream, &tmp, mode)) { | 160 if (!this->onDecode(stream, &tmp, mode)) { |
143 return false; | 161 return false; |
144 } | 162 } |
145 bm->swap(tmp); | 163 bm->swap(tmp); |
146 return true; | 164 return true; |
147 } | 165 } |
148 | 166 |
| 167 bool SkImageDecoder::decodeRegion(SkBitmap* bm, const SkIRect& rect, |
| 168 SkBitmap::Config pref) { |
| 169 // we reset this to false before calling onDecodeRegion |
| 170 fShouldCancelDecode = false; |
| 171 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
| 172 fDefaultPref = pref; |
| 173 |
| 174 return this->onDecodeRegion(bm, rect); |
| 175 } |
| 176 |
| 177 bool SkImageDecoder::buildTileIndex(SkStream* stream, |
| 178 int *width, int *height) { |
| 179 // we reset this to false before calling onBuildTileIndex |
| 180 fShouldCancelDecode = false; |
| 181 |
| 182 return this->onBuildTileIndex(stream, width, height); |
| 183 } |
| 184 |
| 185 void SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
| 186 int dstX, int dstY, int width, int height, |
| 187 int srcX, int srcY) { |
| 188 int w = width / sampleSize; |
| 189 int h = height / sampleSize; |
| 190 // if the destination has no pixels then we must allocate them. |
| 191 if (dst->isNull()) { |
| 192 dst->setConfig(src->getConfig(), w, h); |
| 193 dst->setIsOpaque(src->isOpaque()); |
| 194 |
| 195 if (!this->allocPixelRef(dst, NULL)) { |
| 196 SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); |
| 197 return; |
| 198 } |
| 199 } |
| 200 // check to see if the destination is large enough to decode the desired |
| 201 // region. If this assert fails we will just draw as much of the source |
| 202 // into the destination that we can. |
| 203 SkASSERT(dst->width() >= w && dst->height() >= h); |
| 204 |
| 205 // Set the Src_Mode for the paint to prevent transparency issue in the |
| 206 // dest in the event that the dest was being re-used. |
| 207 SkPaint paint; |
| 208 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 209 |
| 210 SkCanvas canvas(*dst); |
| 211 canvas.drawSprite(*src, (srcX - dstX) / sampleSize, |
| 212 (srcY - dstY) / sampleSize, |
| 213 &paint); |
| 214 } |
| 215 |
149 /////////////////////////////////////////////////////////////////////////////// | 216 /////////////////////////////////////////////////////////////////////////////// |
150 | 217 |
151 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, | 218 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, |
152 SkBitmap::Config pref, Mode mode, Format* format) { | 219 SkBitmap::Config pref, Mode mode, Format* format) { |
153 SkASSERT(file); | 220 SkASSERT(file); |
154 SkASSERT(bm); | 221 SkASSERT(bm); |
155 | 222 |
156 SkFILEStream stream(file); | 223 SkFILEStream stream(file); |
157 if (stream.isValid()) { | 224 if (stream.isValid()) { |
158 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { | 225 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 | 314 |
248 if (NULL != codec) { | 315 if (NULL != codec) { |
249 success = codec->decode(stream, bm, pref, mode); | 316 success = codec->decode(stream, bm, pref, mode); |
250 if (success && format) { | 317 if (success && format) { |
251 *format = codec->getFormat(); | 318 *format = codec->getFormat(); |
252 } | 319 } |
253 delete codec; | 320 delete codec; |
254 } | 321 } |
255 return success; | 322 return success; |
256 } | 323 } |
OLD | NEW |