gecko/image/decoders/nsPNGDecoder.h
Jeff Muizelaar 738a667bbd Bug 1131446. mFrameHasNoAlpha is mostly pointless. r=seth
Starting with bug 391583 we detect whether a png image has any transparency
during decode. I don't think this is worth doing anymore. We choose the format
of image based on the png header, that should be sufficient for the performance
improvement we desire from opaque images. This gets us faster image decoding.
2015-02-10 13:26:14 +08:00

133 lines
3.7 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsPNGDecoder_h
#define nsPNGDecoder_h
#include "Decoder.h"
#include "gfxTypes.h"
#include "nsCOMPtr.h"
#include "png.h"
#include "qcms.h"
namespace mozilla {
namespace image {
class RasterImage;
class nsPNGDecoder : public Decoder
{
public:
explicit nsPNGDecoder(RasterImage* aImage);
virtual ~nsPNGDecoder();
virtual void InitInternal() MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE;
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
int32_t width, int32_t height,
gfx::SurfaceFormat format);
void EndImageFrame();
// Check if PNG is valid ICO (32bpp RGBA)
// http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
bool IsValidICO() const
{
// If there are errors in the call to png_get_IHDR, the error_callback in
// nsPNGDecoder.cpp is called. In this error callback we do a longjmp, so
// we need to save the jump buffer here. Oterwise we'll end up without a
// proper callstack.
if (setjmp(png_jmpbuf(mPNG))) {
// We got here from a longjmp call indirectly from png_get_IHDR
return false;
}
png_uint_32
png_width, // Unused
png_height; // Unused
int png_bit_depth,
png_color_type;
if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth,
&png_color_type, nullptr, nullptr, nullptr)) {
return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_color_type == PNG_COLOR_TYPE_RGB) &&
png_bit_depth == 8);
} else {
return false;
}
}
public:
png_structp mPNG;
png_infop mInfo;
nsIntRect mFrameRect;
uint8_t* mCMSLine;
uint8_t* interlacebuf;
qcms_profile* mInProfile;
qcms_transform* mTransform;
gfx::SurfaceFormat format;
// For size decodes
uint8_t mSizeBytes[8]; // Space for width and height, both 4 bytes
uint32_t mHeaderBytesRead;
// whether CMS or premultiplied alpha are forced off
uint32_t mCMSMode;
uint8_t mChannels;
bool mFrameIsHidden;
bool mDisablePremultipliedAlpha;
struct AnimFrameInfo
{
AnimFrameInfo();
#ifdef PNG_APNG_SUPPORTED
AnimFrameInfo(png_structp aPNG, png_infop aInfo);
#endif
DisposalMethod mDispose;
BlendMethod mBlend;
int32_t mTimeout;
};
AnimFrameInfo mAnimInfo;
// The number of frames we've finished.
uint32_t mNumFrames;
// libpng callbacks
// We put these in the class so that they can access protected members.
static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass);
#ifdef PNG_APNG_SUPPORTED
static void PNGAPI frame_info_callback(png_structp png_ptr,
png_uint_32 frame_num);
#endif
static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
static void PNGAPI error_callback(png_structp png_ptr,
png_const_charp error_msg);
static void PNGAPI warning_callback(png_structp png_ptr,
png_const_charp warning_msg);
// This is defined in the PNG spec as an invariant. We use it to
// do manual validation without libpng.
static const uint8_t pngSignatureBytes[];
};
} // namespace image
} // namespace mozilla
#endif // nsPNGDecoder_h