1 /* libs/graphics/images/SkImageDecoder.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkImageDecoder.h"
19 #include "SkBitmap.h"
20 #include "SkPixelRef.h"
21 #include "SkStream.h"
22 #include "SkTemplates.h"
23
24 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config;
25
GetDeviceConfig()26 SkBitmap::Config SkImageDecoder::GetDeviceConfig()
27 {
28 return gDeviceConfig;
29 }
30
SetDeviceConfig(SkBitmap::Config config)31 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
32 {
33 gDeviceConfig = config;
34 }
35
36 ///////////////////////////////////////////////////////////////////////////////
37
SkImageDecoder()38 SkImageDecoder::SkImageDecoder()
39 : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1),
40 fDitherImage(true) {
41 }
42
~SkImageDecoder()43 SkImageDecoder::~SkImageDecoder() {
44 fPeeker->safeUnref();
45 fChooser->safeUnref();
46 fAllocator->safeUnref();
47 }
48
getFormat() const49 SkImageDecoder::Format SkImageDecoder::getFormat() const {
50 return kUnknown_Format;
51 }
52
setPeeker(Peeker * peeker)53 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
54 SkRefCnt_SafeAssign(fPeeker, peeker);
55 return peeker;
56 }
57
setChooser(Chooser * chooser)58 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
59 SkRefCnt_SafeAssign(fChooser, chooser);
60 return chooser;
61 }
62
setAllocator(SkBitmap::Allocator * alloc)63 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
64 SkRefCnt_SafeAssign(fAllocator, alloc);
65 return alloc;
66 }
67
setSampleSize(int size)68 void SkImageDecoder::setSampleSize(int size) {
69 if (size < 1) {
70 size = 1;
71 }
72 fSampleSize = size;
73 }
74
chooseFromOneChoice(SkBitmap::Config config,int width,int height) const75 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width,
76 int height) const {
77 Chooser* chooser = fChooser;
78
79 if (NULL == chooser) { // no chooser, we just say YES to decoding :)
80 return true;
81 }
82 chooser->begin(1);
83 chooser->inspect(0, config, width, height);
84 return chooser->choose() == 0;
85 }
86
allocPixelRef(SkBitmap * bitmap,SkColorTable * ctable) const87 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
88 SkColorTable* ctable) const {
89 return bitmap->allocPixels(fAllocator, ctable);
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////
93
decode(SkStream * stream,SkBitmap * bm,SkBitmap::Config pref,Mode mode)94 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
95 SkBitmap::Config pref, Mode mode) {
96 // pass a temporary bitmap, so that if we return false, we are assured of
97 // leaving the caller's bitmap untouched.
98 SkBitmap tmp;
99
100 // we reset this to false before calling onDecode
101 fShouldCancelDecode = false;
102
103 if (!this->onDecode(stream, &tmp, pref, mode)) {
104 return false;
105 }
106 bm->swap(tmp);
107 return true;
108 }
109
110 ///////////////////////////////////////////////////////////////////////////////
111
DecodeFile(const char file[],SkBitmap * bm,SkBitmap::Config pref,Mode mode,Format * format)112 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
113 SkBitmap::Config pref, Mode mode, Format* format) {
114 SkASSERT(file);
115 SkASSERT(bm);
116
117 SkFILEStream stream(file);
118 if (stream.isValid()) {
119 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) {
120 bm->pixelRef()->setURI(file);
121 }
122 return true;
123 }
124 return false;
125 }
126
DecodeMemory(const void * buffer,size_t size,SkBitmap * bm,SkBitmap::Config pref,Mode mode,Format * format)127 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
128 SkBitmap::Config pref, Mode mode, Format* format) {
129 if (0 == size) {
130 return false;
131 }
132 SkASSERT(buffer);
133
134 SkMemoryStream stream(buffer, size);
135 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
136 }
137
DecodeStream(SkStream * stream,SkBitmap * bm,SkBitmap::Config pref,Mode mode,Format * format)138 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm,
139 SkBitmap::Config pref, Mode mode, Format* format) {
140 SkASSERT(stream);
141 SkASSERT(bm);
142
143 bool success = false;
144 SkImageDecoder* codec = SkImageDecoder::Factory(stream);
145
146 if (NULL != codec) {
147 success = codec->decode(stream, bm, pref, mode);
148 if (success && format) {
149 *format = codec->getFormat();
150 }
151 delete codec;
152 }
153 return success;
154 }
155
156