/* libs/graphics/images/SkImageDecoder.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include "SkImageDecoder.h"
#include "SkBitmap.h"
#include "SkPixelRef.h"
#include "SkStream.h"
#include "SkTemplates.h"
static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config;
SkBitmap::Config SkImageDecoder::GetDeviceConfig()
{
return gDeviceConfig;
}
void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
{
gDeviceConfig = config;
}
///////////////////////////////////////////////////////////////////////////////
SkImageDecoder::SkImageDecoder()
: fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1),
fDitherImage(true) {
}
SkImageDecoder::~SkImageDecoder() {
fPeeker->safeUnref();
fChooser->safeUnref();
fAllocator->safeUnref();
}
SkImageDecoder::Format SkImageDecoder::getFormat() const {
return kUnknown_Format;
}
SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
SkRefCnt_SafeAssign(fPeeker, peeker);
return peeker;
}
SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
SkRefCnt_SafeAssign(fChooser, chooser);
return chooser;
}
SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
SkRefCnt_SafeAssign(fAllocator, alloc);
return alloc;
}
void SkImageDecoder::setSampleSize(int size) {
if (size < 1) {
size = 1;
}
fSampleSize = size;
}
bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width,
int height) const {
Chooser* chooser = fChooser;
if (NULL == chooser) { // no chooser, we just say YES to decoding :)
return true;
}
chooser->begin(1);
chooser->inspect(0, config, width, height);
return chooser->choose() == 0;
}
bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
SkColorTable* ctable) const {
return bitmap->allocPixels(fAllocator, ctable);
}
///////////////////////////////////////////////////////////////////////////////
bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
SkBitmap::Config pref, Mode mode) {
// pass a temporary bitmap, so that if we return false, we are assured of
// leaving the caller's bitmap untouched.
SkBitmap tmp;
// we reset this to false before calling onDecode
fShouldCancelDecode = false;
if (!this->onDecode(stream, &tmp, pref, mode)) {
return false;
}
bm->swap(tmp);
return true;
}
///////////////////////////////////////////////////////////////////////////////
bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
SkBitmap::Config pref, Mode mode) {
SkASSERT(file);
SkASSERT(bm);
SkFILEStream stream(file);
if (stream.isValid()) {
if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode)) {
bm->pixelRef()->setURI(file);
}
return true;
}
return false;
}
bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
SkBitmap::Config pref, Mode mode) {
if (0 == size) {
return false;
}
SkASSERT(buffer);
SkMemoryStream stream(buffer, size);
return SkImageDecoder::DecodeStream(&stream, bm, pref, mode);
}
bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm,
SkBitmap::Config pref, Mode mode) {
SkASSERT(stream);
SkASSERT(bm);
bool success = false;
SkImageDecoder* codec = SkImageDecoder::Factory(stream);
if (NULL != codec) {
success = codec->decode(stream, bm, pref, mode);
delete codec;
}
return success;
}