Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / images / SkImageDecoder.cpp
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8
9 #include "SkImageDecoder.h"
10 #include "SkBitmap.h"
11 #include "SkImagePriv.h"
12 #include "SkPixelRef.h"
13 #include "SkStream.h"
14 #include "SkTemplates.h"
15 #include "SkCanvas.h"
16
17 SkImageDecoder::SkImageDecoder()
18     : fPeeker(NULL)
19 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
20     , fChooser(NULL)
21 #endif
22     , fAllocator(NULL)
23     , fSampleSize(1)
24     , fDefaultPref(kUnknown_SkColorType)
25     , fPreserveSrcDepth(false)
26     , fDitherImage(true)
27     , fSkipWritingZeroes(false)
28     , fPreferQualityOverSpeed(false)
29     , fRequireUnpremultipliedColors(false) {
30 }
31
32 SkImageDecoder::~SkImageDecoder() {
33     SkSafeUnref(fPeeker);
34 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
35     SkSafeUnref(fChooser);
36 #endif
37     SkSafeUnref(fAllocator);
38 }
39
40 void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
41     if (NULL == other) {
42         return;
43     }
44     other->setPeeker(fPeeker);
45 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
46     other->setChooser(fChooser);
47 #endif
48     other->setAllocator(fAllocator);
49     other->setSampleSize(fSampleSize);
50     other->setPreserveSrcDepth(fPreserveSrcDepth);
51     other->setDitherImage(fDitherImage);
52     other->setSkipWritingZeroes(fSkipWritingZeroes);
53     other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
54     other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
55 }
56
57 SkImageDecoder::Format SkImageDecoder::getFormat() const {
58     return kUnknown_Format;
59 }
60
61 const char* SkImageDecoder::getFormatName() const {
62     return GetFormatName(this->getFormat());
63 }
64
65 const char* SkImageDecoder::GetFormatName(Format format) {
66     switch (format) {
67         case kUnknown_Format:
68             return "Unknown Format";
69         case kBMP_Format:
70             return "BMP";
71         case kGIF_Format:
72             return "GIF";
73         case kICO_Format:
74             return "ICO";
75         case kPKM_Format:
76             return "PKM";
77         case kKTX_Format:
78             return "KTX";
79         case kASTC_Format:
80             return "ASTC";
81         case kJPEG_Format:
82             return "JPEG";
83         case kPNG_Format:
84             return "PNG";
85         case kWBMP_Format:
86             return "WBMP";
87         case kWEBP_Format:
88             return "WEBP";
89         default:
90             SkDEBUGFAIL("Invalid format type!");
91     }
92     return "Unknown Format";
93 }
94
95 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
96     SkRefCnt_SafeAssign(fPeeker, peeker);
97     return peeker;
98 }
99
100 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
101 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
102     SkRefCnt_SafeAssign(fChooser, chooser);
103     return chooser;
104 }
105 #endif
106
107 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
108     SkRefCnt_SafeAssign(fAllocator, alloc);
109     return alloc;
110 }
111
112 void SkImageDecoder::setSampleSize(int size) {
113     if (size < 1) {
114         size = 1;
115     }
116     fSampleSize = size;
117 }
118
119 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
120 // TODO: change Chooser virtual to take colorType, so we can stop calling SkColorTypeToBitmapConfig
121 //
122 bool SkImageDecoder::chooseFromOneChoice(SkColorType colorType, int width, int height) const {
123     Chooser* chooser = fChooser;
124     
125     if (NULL == chooser) {    // no chooser, we just say YES to decoding :)
126         return true;
127     }
128     chooser->begin(1);
129     chooser->inspect(0, SkColorTypeToBitmapConfig(colorType), width, height);
130     return chooser->choose() == 0;
131 }
132 #endif
133
134 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
135                                    SkColorTable* ctable) const {
136     return bitmap->tryAllocPixels(fAllocator, ctable);
137 }
138
139 ///////////////////////////////////////////////////////////////////////////////
140
141 SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const {
142     SkColorType ct = fDefaultPref;
143     if (fPreserveSrcDepth) {
144         switch (srcDepth) {
145             case kIndex_SrcDepth:
146                 ct = kIndex_8_SkColorType;
147                 break;
148             case k8BitGray_SrcDepth:
149                 ct = kN32_SkColorType;
150                 break;
151             case k32Bit_SrcDepth:
152                 ct = kN32_SkColorType;
153                 break;
154         }
155     }
156     return ct;
157 }
158
159 SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref,
160                                               Mode mode) {
161     // we reset this to false before calling onDecode
162     fShouldCancelDecode = false;
163     // assign this, for use by getPrefColorType(), in case fUsePrefTable is false
164     fDefaultPref = pref;
165
166     // pass a temporary bitmap, so that if we return false, we are assured of
167     // leaving the caller's bitmap untouched.
168     SkBitmap tmp;
169     const Result result = this->onDecode(stream, &tmp, mode);
170     if (kFailure != result) {
171         bm->swap(tmp);
172     }
173     return result;
174 }
175
176 bool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, SkColorType pref) {
177     // we reset this to false before calling onDecodeSubset
178     fShouldCancelDecode = false;
179     // assign this, for use by getPrefColorType(), in case fUsePrefTable is false
180     fDefaultPref = pref;
181
182     return this->onDecodeSubset(bm, rect);
183 }
184
185 bool SkImageDecoder::buildTileIndex(SkStreamRewindable* stream, int *width, int *height) {
186     // we reset this to false before calling onBuildTileIndex
187     fShouldCancelDecode = false;
188
189     return this->onBuildTileIndex(stream, width, height);
190 }
191
192 bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize,
193                                 int dstX, int dstY, int width, int height,
194                                 int srcX, int srcY) {
195     int w = width / sampleSize;
196     int h = height / sampleSize;
197     if (src->colorType() == kIndex_8_SkColorType) {
198         // kIndex8 does not allow drawing via an SkCanvas, as is done below.
199         // Instead, use extractSubset. Note that this shares the SkPixelRef and
200         // SkColorTable.
201         // FIXME: Since src is discarded in practice, this holds on to more
202         // pixels than is strictly necessary. Switch to a copy if memory
203         // savings are more important than speed here. This also means
204         // that the pixels in dst can not be reused (though there is no
205         // allocation, which was already done on src).
206         int x = (dstX - srcX) / sampleSize;
207         int y = (dstY - srcY) / sampleSize;
208         SkIRect subset = SkIRect::MakeXYWH(x, y, w, h);
209         return src->extractSubset(dst, subset);
210     }
211     // if the destination has no pixels then we must allocate them.
212     if (dst->isNull()) {
213         dst->setInfo(src->info().makeWH(w, h));
214
215         if (!this->allocPixelRef(dst, NULL)) {
216             SkDEBUGF(("failed to allocate pixels needed to crop the bitmap"));
217             return false;
218         }
219     }
220     // check to see if the destination is large enough to decode the desired
221     // region. If this assert fails we will just draw as much of the source
222     // into the destination that we can.
223     if (dst->width() < w || dst->height() < h) {
224         SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n"));
225     }
226
227     // Set the Src_Mode for the paint to prevent transparency issue in the
228     // dest in the event that the dest was being re-used.
229     SkPaint paint;
230     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
231
232     SkCanvas canvas(*dst);
233     canvas.drawSprite(*src, (srcX - dstX) / sampleSize,
234                             (srcY - dstY) / sampleSize,
235                             &paint);
236     return true;
237 }
238
239 ///////////////////////////////////////////////////////////////////////////////
240
241 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pref,  Mode mode,
242                                 Format* format) {
243     SkASSERT(file);
244     SkASSERT(bm);
245
246     SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(file));
247     if (stream.get()) {
248         if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
249             bm->pixelRef()->setURI(file);
250             return true;
251         }
252     }
253     return false;
254 }
255
256 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, SkColorType pref,
257                                   Mode mode, Format* format) {
258     if (0 == size) {
259         return false;
260     }
261     SkASSERT(buffer);
262
263     SkMemoryStream  stream(buffer, size);
264     return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
265 }
266
267 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkColorType pref,
268                                   Mode mode, Format* format) {
269     SkASSERT(stream);
270     SkASSERT(bm);
271
272     bool success = false;
273     SkImageDecoder* codec = SkImageDecoder::Factory(stream);
274
275     if (codec) {
276         success = codec->decode(stream, bm, pref, mode) != kFailure;
277         if (success && format) {
278             *format = codec->getFormat();
279             if (kUnknown_Format == *format) {
280                 if (stream->rewind()) {
281                     *format = GetStreamFormat(stream);
282                 }
283             }
284         }
285         delete codec;
286     }
287     return success;
288 }
289
290 bool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
291                                       size_t rowBytes[3], SkYUVColorSpace* colorSpace) {
292     // we reset this to false before calling onDecodeYUV8Planes
293     fShouldCancelDecode = false;
294
295     return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, colorSpace);
296 }