Bug 812602. Don't decode jpegs progressively when we have all the data. r=joe

Decoding progressively is slower because we duplicate work like color
conversion and color correction for each outputted scan. We already suppress
paints when have all of the data, so we shouldn't do this extra work.

--HG--
extra : rebase_source : e6dd733546e1bb9e6e3279d9ceea0b4c0a88e049
This commit is contained in:
Jeff Muizelaar 2012-11-18 20:18:52 -05:00
parent f41b18a4d6
commit 2c4d59c7eb
4 changed files with 18 additions and 5 deletions

View File

@ -82,8 +82,9 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo);
#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
nsJPEGDecoder::nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsJPEGDecoder::nsJPEGDecoder(RasterImage& aImage, imgIDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle)
: Decoder(aImage, aObserver)
, mDecodeStyle(aDecodeStyle)
{
mState = JPEG_HEADER;
mReading = true;
@ -365,9 +366,9 @@ nsJPEGDecoder::WriteInternal(const char *aBuffer, uint32_t aCount)
/*
* Don't allocate a giant and superfluous memory buffer
* when the image is a sequential JPEG.
* when not doing a progressive decode.
*/
mInfo.buffered_image = jpeg_has_multiple_scans(&mInfo);
mInfo.buffered_image = mDecodeStyle == PROGRESSIVE && jpeg_has_multiple_scans(&mInfo);
/* Used to set up image size so arrays can be allocated */
jpeg_calc_output_dimensions(&mInfo);

View File

@ -52,7 +52,7 @@ class RasterImage;
class nsJPEGDecoder : public Decoder
{
public:
nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle);
virtual ~nsJPEGDecoder();
virtual void InitInternal();
@ -91,6 +91,8 @@ public:
bool mReading;
const Decoder::DecodeStyle mDecodeStyle;
uint32_t mCMSMode;
};

View File

@ -120,6 +120,12 @@ public:
DECODER_NO_PREMULTIPLY_ALPHA = 0x2, // imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA
DECODER_NO_COLORSPACE_CONVERSION = 0x4 // imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION
};
enum DecodeStyle {
PROGRESSIVE, // produce intermediate frames representing the partial state of the image
SEQUENTIAL // decode to final image immediately
};
void SetDecodeFlags(uint32_t aFlags) { mDecodeFlags = aFlags; }
uint32_t GetDecodeFlags() { return mDecodeFlags; }

View File

@ -2522,7 +2522,11 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
mDecoder = new nsGIFDecoder2(*this, observer);
break;
case eDecoderType_jpeg:
mDecoder = new nsJPEGDecoder(*this, observer);
// If we have all the data we don't want to waste cpu time doing
// a progressive decode
mDecoder = new nsJPEGDecoder(*this, observer,
mHasBeenDecoded ? Decoder::DecodeStyle::SEQUENTIAL :
Decoder::DecodeStyle::PROGRESSIVE);
break;
case eDecoderType_bmp:
mDecoder = new nsBMPDecoder(*this, observer);