blob: 18b52d689caf4298543473c5c3059087be1cb799 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* 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
24static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config;
25
26SkBitmap::Config SkImageDecoder::GetDeviceConfig()
27{
28 return gDeviceConfig;
29}
30
31void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
32{
33 gDeviceConfig = config;
34}
35
36///////////////////////////////////////////////////////////////////////////////
37
38SkImageDecoder::SkImageDecoder()
39 : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1),
40 fDitherImage(true) {
41}
42
43SkImageDecoder::~SkImageDecoder() {
44 fPeeker->safeUnref();
45 fChooser->safeUnref();
46 fAllocator->safeUnref();
47}
48
49SkImageDecoder::Format SkImageDecoder::getFormat() const {
50 return kUnknown_Format;
51}
52
53SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
54 SkRefCnt_SafeAssign(fPeeker, peeker);
55 return peeker;
56}
57
58SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
59 SkRefCnt_SafeAssign(fChooser, chooser);
60 return chooser;
61}
62
63SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
64 SkRefCnt_SafeAssign(fAllocator, alloc);
65 return alloc;
66}
67
68void SkImageDecoder::setSampleSize(int size) {
69 if (size < 1) {
70 size = 1;
71 }
72 fSampleSize = size;
73}
74
75bool 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
87bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
88 SkColorTable* ctable) const {
89 return bitmap->allocPixels(fAllocator, ctable);
90}
91
92///////////////////////////////////////////////////////////////////////////////
93
94bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
95 SkBitmap::Config pref, Mode mode) {
96 SkBitmap tmp;
97
98 // we reset this to false before calling onDecode
99 fShouldCancelDecode = false;
100
101 // pass a temporary bitmap, so that if we return false, we are assured of
102 // leaving the caller's bitmap untouched.
103 if (this->onDecode(stream, &tmp, pref, mode)) {
104 /* We operate on a tmp bitmap until we know we succeed. This way
105 we're sure we don't change the caller's bitmap and then later
106 return false. Returning false must mean that their parameter
107 is unchanged.
108 */
109 bm->swap(tmp);
110 return true;
111 }
112 return false;
113}
114
115///////////////////////////////////////////////////////////////////////////////
116
117bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
118 SkBitmap::Config pref, Mode mode) {
119 SkASSERT(file);
120 SkASSERT(bm);
121
122 SkFILEStream stream(file);
123 if (stream.isValid()) {
124 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode)) {
125 bm->pixelRef()->setURI(file);
126 }
127 return true;
128 }
129 return false;
130}
131
132bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
133 SkBitmap::Config pref, Mode mode) {
134 if (0 == size) {
135 return false;
136 }
137 SkASSERT(buffer);
138
139 SkMemoryStream stream(buffer, size);
140 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode);
141}
142
143bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm,
144 SkBitmap::Config pref, Mode mode) {
145 SkASSERT(stream);
146 SkASSERT(bm);
147
148 bool success = false;
149 SkImageDecoder* codec = SkImageDecoder::Factory(stream);
150
151 if (NULL != codec) {
152 success = codec->decode(stream, bm, pref, mode);
153 delete codec;
154 }
155 return success;
156}
157
158///////////////////////////////////////////////////////////////////////////////
159
160#ifdef SK_SUPPORT_IMAGE_ENCODE
161
162SkImageEncoder::~SkImageEncoder() {}
163
164bool SkImageEncoder::encodeStream(SkWStream* stream, const SkBitmap& bm,
165 int quality) {
166 quality = SkMin32(100, SkMax32(0, quality));
167 return this->onEncode(stream, bm, quality);
168}
169
170bool SkImageEncoder::encodeFile(const char file[], const SkBitmap& bm,
171 int quality) {
172 quality = SkMin32(100, SkMax32(0, quality));
173 SkFILEWStream stream(file);
174 return this->onEncode(&stream, bm, quality);
175}
176
177bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap& bm, Type t,
178 int quality) {
179 SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t));
180 return enc.get() && enc.get()->encodeFile(file, bm, quality);
181}
182
183bool SkImageEncoder::EncodeStream(SkWStream* stream, const SkBitmap& bm, Type t,
184 int quality) {
185 SkAutoTDelete<SkImageEncoder> enc(SkImageEncoder::Create(t));
186 return enc.get() && enc.get()->encodeStream(stream, bm, quality);
187}
188
189#endif
190