1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/image/decoders/nsPNGDecoder.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,136 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef nsPNGDecoder_h__ 1.11 +#define nsPNGDecoder_h__ 1.12 + 1.13 +#include "Decoder.h" 1.14 + 1.15 +#include "gfxTypes.h" 1.16 + 1.17 +#include "nsCOMPtr.h" 1.18 + 1.19 +#include "png.h" 1.20 + 1.21 +#include "qcms.h" 1.22 + 1.23 +namespace mozilla { 1.24 +namespace image { 1.25 +class RasterImage; 1.26 + 1.27 +class nsPNGDecoder : public Decoder 1.28 +{ 1.29 +public: 1.30 + nsPNGDecoder(RasterImage &aImage); 1.31 + virtual ~nsPNGDecoder(); 1.32 + 1.33 + virtual void InitInternal(); 1.34 + virtual void WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy); 1.35 + virtual Telemetry::ID SpeedHistogram(); 1.36 + 1.37 + void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, 1.38 + int32_t width, int32_t height, 1.39 + gfxImageFormat format); 1.40 + void EndImageFrame(); 1.41 + 1.42 + // Check if PNG is valid ICO (32bpp RGBA) 1.43 + // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx 1.44 + bool IsValidICO() const 1.45 + { 1.46 + // If there are errors in the call to png_get_IHDR, the error_callback in 1.47 + // nsPNGDecoder.cpp is called. In this error callback we do a longjmp, so 1.48 + // we need to save the jump buffer here. Oterwise we'll end up without a 1.49 + // proper callstack. 1.50 + if (setjmp(png_jmpbuf(mPNG))) { 1.51 + // We got here from a longjmp call indirectly from png_get_IHDR 1.52 + return false; 1.53 + } 1.54 + 1.55 + png_uint_32 1.56 + png_width, // Unused 1.57 + png_height; // Unused 1.58 + 1.59 + int png_bit_depth, 1.60 + png_color_type; 1.61 + 1.62 + if (png_get_IHDR(mPNG, mInfo, &png_width, &png_height, &png_bit_depth, 1.63 + &png_color_type, nullptr, nullptr, nullptr)) { 1.64 + 1.65 + return ((png_color_type == PNG_COLOR_TYPE_RGB_ALPHA || 1.66 + png_color_type == PNG_COLOR_TYPE_RGB) && 1.67 + png_bit_depth == 8); 1.68 + } else { 1.69 + return false; 1.70 + } 1.71 + } 1.72 + 1.73 +public: 1.74 + png_structp mPNG; 1.75 + png_infop mInfo; 1.76 + nsIntRect mFrameRect; 1.77 + uint8_t *mCMSLine; 1.78 + uint8_t *interlacebuf; 1.79 + qcms_profile *mInProfile; 1.80 + qcms_transform *mTransform; 1.81 + 1.82 + gfxImageFormat format; 1.83 + 1.84 + // For size decodes 1.85 + uint8_t mSizeBytes[8]; // Space for width and height, both 4 bytes 1.86 + uint32_t mHeaderBytesRead; 1.87 + 1.88 + // whether CMS or premultiplied alpha are forced off 1.89 + uint32_t mCMSMode; 1.90 + 1.91 + uint8_t mChannels; 1.92 + bool mFrameHasNoAlpha; 1.93 + bool mFrameIsHidden; 1.94 + bool mDisablePremultipliedAlpha; 1.95 + 1.96 + struct AnimFrameInfo 1.97 + { 1.98 + AnimFrameInfo(); 1.99 +#ifdef PNG_APNG_SUPPORTED 1.100 + AnimFrameInfo(png_structp aPNG, png_infop aInfo); 1.101 +#endif 1.102 + 1.103 + FrameBlender::FrameDisposalMethod mDispose; 1.104 + FrameBlender::FrameBlendMethod mBlend; 1.105 + int32_t mTimeout; 1.106 + }; 1.107 + 1.108 + AnimFrameInfo mAnimInfo; 1.109 + 1.110 + // The number of frames we've finished. 1.111 + uint32_t mNumFrames; 1.112 + 1.113 + /* 1.114 + * libpng callbacks 1.115 + * 1.116 + * We put these in the class so that they can access protected members. 1.117 + */ 1.118 + static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr); 1.119 + static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row, 1.120 + png_uint_32 row_num, int pass); 1.121 +#ifdef PNG_APNG_SUPPORTED 1.122 + static void PNGAPI frame_info_callback(png_structp png_ptr, 1.123 + png_uint_32 frame_num); 1.124 +#endif 1.125 + static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr); 1.126 + static void PNGAPI error_callback(png_structp png_ptr, 1.127 + png_const_charp error_msg); 1.128 + static void PNGAPI warning_callback(png_structp png_ptr, 1.129 + png_const_charp warning_msg); 1.130 + 1.131 + // This is defined in the PNG spec as an invariant. We use it to 1.132 + // do manual validation without libpng. 1.133 + static const uint8_t pngSignatureBytes[]; 1.134 +}; 1.135 + 1.136 +} // namespace image 1.137 +} // namespace mozilla 1.138 + 1.139 +#endif // nsPNGDecoder_h__