зеркало из https://github.com/mozilla/moz-skia.git
add optional pref-config table to codecs
git-svn-id: http://skia.googlecode.com/svn/trunk@519 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
8de2e6de5b
Коммит
3f1f06a26b
|
@ -89,6 +89,33 @@ public:
|
|||
Chooser* getChooser() const { return fChooser; }
|
||||
Chooser* setChooser(Chooser*);
|
||||
|
||||
/** This optional table describes the caller's preferred config based on
|
||||
information about the src data. For this table, the src attributes are
|
||||
described in terms of depth (index (8), 16, 32/24) and if there is
|
||||
per-pixel alpha. These inputs combine to create an index into the
|
||||
pref[] table, which contains the caller's preferred config for that
|
||||
input, or kNo_Config if there is no preference.
|
||||
|
||||
To specify no preferrence, call setPrefConfigTable(NULL), which is
|
||||
the default.
|
||||
|
||||
Note, it is still at the discretion of the codec as to what output
|
||||
config is actually returned, as it may not be able to support the
|
||||
caller's preference.
|
||||
|
||||
Here is how the index into the table is computed from the src:
|
||||
depth [8, 16, 32/24] -> 0, 2, 4
|
||||
alpha [no, yes] -> 0, 1
|
||||
The two index values are OR'd together.
|
||||
src: 8-index, no-alpha -> 0
|
||||
src: 8-index, yes-alpha -> 1
|
||||
src: 16bit, no-alpha -> 2 // e.g. 565
|
||||
src: 16bit, yes-alpha -> 3 // e.g. 1555
|
||||
src: 32/24, no-alpha -> 4
|
||||
src: 32/24, yes-alpha -> 5
|
||||
*/
|
||||
void setPrefConfigTable(const SkBitmap::Config pref[6]);
|
||||
|
||||
SkBitmap::Allocator* getAllocator() const { return fAllocator; }
|
||||
SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
|
||||
|
||||
|
@ -145,6 +172,9 @@ public:
|
|||
note: document use of Allocator, Peeker and Chooser
|
||||
*/
|
||||
bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
|
||||
bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
|
||||
return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
|
||||
}
|
||||
|
||||
/** Given a stream, this will try to find an appropriate decoder object.
|
||||
If none is found, the method returns NULL.
|
||||
|
@ -232,8 +262,7 @@ public:
|
|||
|
||||
protected:
|
||||
// must be overridden in subclasses. This guy is called by decode(...)
|
||||
virtual bool onDecode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref,
|
||||
Mode) = 0;
|
||||
virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
|
||||
|
||||
/** Can be queried from within onDecode, to see if the user (possibly in
|
||||
a different thread) has requested the decode to cancel. If this returns
|
||||
|
@ -260,12 +289,30 @@ protected:
|
|||
*/
|
||||
bool allocPixelRef(SkBitmap*, SkColorTable*) const;
|
||||
|
||||
enum SrcDepth {
|
||||
kIndex_SrcDepth,
|
||||
k16Bit_SrcDepth,
|
||||
k32Bit_SrcDepth
|
||||
};
|
||||
/** The subclass, inside onDecode(), calls this to determine the config of
|
||||
the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
|
||||
src image. This routine returns the caller's preference given
|
||||
srcDepth and hasAlpha, or kNo_Config if there is no preference.
|
||||
|
||||
Note: this also takes into account GetDeviceConfig(), so the subclass
|
||||
need not call that.
|
||||
*/
|
||||
SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const;
|
||||
|
||||
private:
|
||||
Peeker* fPeeker;
|
||||
Chooser* fChooser;
|
||||
SkBitmap::Allocator* fAllocator;
|
||||
int fSampleSize;
|
||||
SkBitmap::Config fDefaultPref; // use if fUsePrefTable is false
|
||||
SkBitmap::Config fPrefTable[6]; // use if fUsePrefTable is true
|
||||
bool fDitherImage;
|
||||
bool fUsePrefTable;
|
||||
mutable bool fShouldCancelDecode;
|
||||
|
||||
// illegal
|
||||
|
|
|
@ -37,7 +37,8 @@ void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
|
|||
|
||||
SkImageDecoder::SkImageDecoder()
|
||||
: fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1),
|
||||
fDitherImage(true) {
|
||||
fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true),
|
||||
fUsePrefTable(false) {
|
||||
}
|
||||
|
||||
SkImageDecoder::~SkImageDecoder() {
|
||||
|
@ -91,6 +92,46 @@ bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) {
|
||||
if (NULL == pref) {
|
||||
fUsePrefTable = false;
|
||||
} else {
|
||||
fUsePrefTable = true;
|
||||
memcpy(fPrefTable, pref, sizeof(fPrefTable));
|
||||
}
|
||||
}
|
||||
|
||||
SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
|
||||
bool srcHasAlpha) const {
|
||||
SkBitmap::Config config;
|
||||
|
||||
if (fUsePrefTable) {
|
||||
int index = 0;
|
||||
switch (srcDepth) {
|
||||
case kIndex_SrcDepth:
|
||||
index = 0;
|
||||
break;
|
||||
case k16Bit_SrcDepth:
|
||||
index = 2;
|
||||
break;
|
||||
case k32Bit_SrcDepth:
|
||||
index = 4;
|
||||
break;
|
||||
}
|
||||
if (srcHasAlpha) {
|
||||
index += 1;
|
||||
}
|
||||
config = fPrefTable[index];
|
||||
} else {
|
||||
config = fDefaultPref;
|
||||
}
|
||||
|
||||
if (SkBitmap::kNo_Config == config) {
|
||||
config = SkImageDecoder::GetDeviceConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -99,8 +140,10 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
|
|||
|
||||
// we reset this to false before calling onDecode
|
||||
fShouldCancelDecode = false;
|
||||
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false
|
||||
fDefaultPref = pref;
|
||||
|
||||
if (!this->onDecode(stream, &tmp, pref, mode)) {
|
||||
if (!this->onDecode(stream, &tmp, mode)) {
|
||||
return false;
|
||||
}
|
||||
bm->swap(tmp);
|
||||
|
|
|
@ -31,8 +31,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
|
||||
};
|
||||
|
||||
static SkImageDecoder* Factory(SkStream* stream) {
|
||||
|
@ -81,8 +80,7 @@ private:
|
|||
bool fJustBounds;
|
||||
};
|
||||
|
||||
bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config prefConfig, Mode mode) {
|
||||
bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
||||
|
||||
size_t length = stream->getLength();
|
||||
SkAutoMalloc storage(length);
|
||||
|
@ -110,12 +108,12 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
|
|||
|
||||
int width = callback.width();
|
||||
int height = callback.height();
|
||||
SkBitmap::Config config = SkBitmap::kARGB_8888_Config;
|
||||
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
|
||||
|
||||
// only accept prefConfig if it makes sense for us
|
||||
if (SkBitmap::kARGB_4444_Config == prefConfig ||
|
||||
SkBitmap::kRGB_565_Config == config) {
|
||||
config = prefConfig;
|
||||
if (SkBitmap::kARGB_4444_Config != config &&
|
||||
SkBitmap::kRGB_565_Config != config) {
|
||||
config = SkBitmap::kARGB_8888_Config;
|
||||
}
|
||||
|
||||
SkScaledBitmapSampler sampler(width, height, getSampleSize());
|
||||
|
|
|
@ -31,8 +31,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
|
||||
};
|
||||
|
||||
static const uint8_t gStartingIterlaceYValue[] = {
|
||||
|
@ -154,8 +153,7 @@ static bool error_return(GifFileType* gif, const SkBitmap& bm,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm,
|
||||
SkBitmap::Config prefConfig, Mode mode) {
|
||||
bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
|
||||
GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc);
|
||||
if (NULL == gif) {
|
||||
return error_return(gif, *bm, "DGifOpen");
|
||||
|
|
|
@ -29,8 +29,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -79,8 +78,7 @@ static int calculateRowBytesFor8888(int w, int bitCount)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode mode)
|
||||
bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode)
|
||||
{
|
||||
size_t length = stream->read(NULL, 0);
|
||||
SkAutoMalloc autoMal(length);
|
||||
|
|
|
@ -55,8 +55,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -157,8 +156,7 @@ static bool return_false(const jpeg_decompress_struct& cinfo,
|
|||
return false; // must always return false
|
||||
}
|
||||
|
||||
bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config prefConfig, Mode mode) {
|
||||
bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
||||
#ifdef TIME_DECODE
|
||||
AutoTimeMillis atm("JPEG Decode");
|
||||
#endif
|
||||
|
@ -215,11 +213,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
|
|||
/* default format is RGB */
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
|
||||
SkBitmap::Config config = prefConfig;
|
||||
// if no user preference, see what the device recommends
|
||||
if (config == SkBitmap::kNo_Config)
|
||||
config = SkImageDecoder::GetDeviceConfig();
|
||||
|
||||
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
|
||||
// only these make sense for jpegs
|
||||
if (config != SkBitmap::kARGB_8888_Config &&
|
||||
config != SkBitmap::kARGB_4444_Config &&
|
||||
|
|
|
@ -37,8 +37,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
||||
};
|
||||
|
||||
#ifndef png_jmpbuf
|
||||
|
@ -110,9 +109,9 @@ static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) {
|
|||
return reallyHasAlpha;
|
||||
}
|
||||
|
||||
static bool canUpscalePaletteToConfig(SkBitmap::Config prefConfig,
|
||||
static bool canUpscalePaletteToConfig(SkBitmap::Config dstConfig,
|
||||
bool srcHasAlpha) {
|
||||
switch (prefConfig) {
|
||||
switch (dstConfig) {
|
||||
case SkBitmap::kARGB_8888_Config:
|
||||
case SkBitmap::kARGB_4444_Config:
|
||||
return true;
|
||||
|
@ -137,7 +136,7 @@ static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
|
|||
}
|
||||
|
||||
bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
||||
SkBitmap::Config prefConfig, Mode mode) {
|
||||
Mode mode) {
|
||||
// SkAutoTrace apr("SkPNGImageDecoder::onDecode");
|
||||
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
|
@ -233,11 +232,11 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
config = SkBitmap::kIndex8_Config;
|
||||
// now see if we can upscale to their requested config
|
||||
bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
|
||||
if (canUpscalePaletteToConfig(prefConfig, paletteHasAlpha)) {
|
||||
config = prefConfig;
|
||||
config = this->getPrefConfig(kIndex_SrcDepth, paletteHasAlpha);
|
||||
// now see if we can upscale to their requested config
|
||||
if (!canUpscalePaletteToConfig(config, paletteHasAlpha)) {
|
||||
config = SkBitmap::kIndex8_Config;
|
||||
}
|
||||
} else {
|
||||
png_color_16p transpColor = NULL;
|
||||
|
@ -278,12 +277,14 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||
PNG_COLOR_TYPE_RGB_ALPHA == color_type ||
|
||||
PNG_COLOR_TYPE_GRAY_ALPHA == color_type) {
|
||||
hasAlpha = true;
|
||||
config = SkBitmap::kARGB_8888_Config;
|
||||
} else { // we get to choose the config
|
||||
config = prefConfig;
|
||||
if (config == SkBitmap::kNo_Config) {
|
||||
config = SkImageDecoder::GetDeviceConfig();
|
||||
}
|
||||
config = this->getPrefConfig(k32Bit_SrcDepth, hasAlpha);
|
||||
// now match the request against our capabilities
|
||||
if (hasAlpha) {
|
||||
if (config != SkBitmap::kARGB_4444_Config) {
|
||||
config = SkBitmap::kARGB_8888_Config;
|
||||
}
|
||||
} else {
|
||||
if (config != SkBitmap::kRGB_565_Config &&
|
||||
config != SkBitmap::kARGB_4444_Config) {
|
||||
config = SkBitmap::kARGB_8888_Config;
|
||||
|
@ -311,9 +312,6 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||
const int sampleSize = this->getSampleSize();
|
||||
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
|
||||
|
||||
// we must always return the same config, independent of mode, so if we were
|
||||
// going to respect prefConfig, it must have happened by now
|
||||
|
||||
decodedBitmap->setConfig(config, sampler.scaledWidth(),
|
||||
sampler.scaledHeight(), 0);
|
||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||
|
|
|
@ -29,8 +29,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
||||
};
|
||||
|
||||
static bool read_byte(SkStream* stream, uint8_t* data)
|
||||
|
@ -107,7 +106,7 @@ static void expand_bits_to_bytes(uint8_t dst[], const uint8_t src[], int bits)
|
|||
#define SkAlign8(x) (((x) + 7) & ~7)
|
||||
|
||||
bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
|
||||
SkBitmap::Config prefConfig, Mode mode)
|
||||
Mode mode)
|
||||
{
|
||||
wbmp_head head;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) {
|
|||
static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
|
||||
skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
|
||||
|
||||
if (num_bytes > src->bytes_in_buffer) {
|
||||
if (num_bytes > (long)src->bytes_in_buffer) {
|
||||
long bytesToSkip = num_bytes - src->bytes_in_buffer;
|
||||
while (bytesToSkip > 0) {
|
||||
long bytes = (long)src->fStream->skip(bytesToSkip);
|
||||
|
|
|
@ -42,14 +42,12 @@ static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) {
|
|||
|
||||
class SkImageDecoder_CG : public SkImageDecoder {
|
||||
protected:
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode);
|
||||
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
|
||||
};
|
||||
|
||||
#define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast)
|
||||
|
||||
bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm,
|
||||
SkBitmap::Config pref, Mode mode) {
|
||||
bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
||||
CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream);
|
||||
|
||||
if (NULL == imageSrc) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче