blob: 4711f89d7f13439e775a7f904a1c4695f48594ca [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**
weita@google.com25e98342009-05-11 16:06:22 +00005** 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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008**
weita@google.com25e98342009-05-11 16:06:22 +00009** http://www.apache.org/licenses/LICENSE-2.0
reed@android.com8a1c16f2008-12-17 15:59:43 +000010**
weita@google.com25e98342009-05-11 16:06:22 +000011** 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
reed@android.com8a1c16f2008-12-17 15:59:43 +000015** 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///////////////////////////////////////////////////////////////////////////////
reed@android.comb6137c32009-07-29 20:56:52 +000093
reed@android.com8a1c16f2008-12-17 15:59:43 +000094bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
95 SkBitmap::Config pref, Mode mode) {
reed@android.com62900b42009-02-11 15:07:19 +000096 // pass a temporary bitmap, so that if we return false, we are assured of
97 // leaving the caller's bitmap untouched.
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 SkBitmap tmp;
99
100 // we reset this to false before calling onDecode
101 fShouldCancelDecode = false;
102
reed@android.com62900b42009-02-11 15:07:19 +0000103 if (!this->onDecode(stream, &tmp, pref, mode)) {
104 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105 }
reed@android.com62900b42009-02-11 15:07:19 +0000106 bm->swap(tmp);
107 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108}
109
110///////////////////////////////////////////////////////////////////////////////
111
112bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000113 SkBitmap::Config pref, Mode mode, Format* format) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 SkASSERT(file);
115 SkASSERT(bm);
116
117 SkFILEStream stream(file);
118 if (stream.isValid()) {
reed@android.comb3ade9d2009-06-15 13:04:45 +0000119 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000120 bm->pixelRef()->setURI(file);
121 }
122 return true;
123 }
124 return false;
125}
126
127bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000128 SkBitmap::Config pref, Mode mode, Format* format) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 if (0 == size) {
130 return false;
131 }
132 SkASSERT(buffer);
133
134 SkMemoryStream stream(buffer, size);
reed@android.comb3ade9d2009-06-15 13:04:45 +0000135 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136}
137
138bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm,
reed@android.comb3ade9d2009-06-15 13:04:45 +0000139 SkBitmap::Config pref, Mode mode, Format* format) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000140 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);
reed@android.comb3ade9d2009-06-15 13:04:45 +0000148 if (success && format) {
149 *format = codec->getFormat();
150 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000151 delete codec;
152 }
153 return success;
154}
155