tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsPNGDecoder.h (4788B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 *
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_image_decoders_nsPNGDecoder_h
      8 #define mozilla_image_decoders_nsPNGDecoder_h
      9 
     10 #include "Decoder.h"
     11 #include "png.h"
     12 #include "StreamingLexer.h"
     13 #include "SurfacePipe.h"
     14 #include "mozilla/gfx/Swizzle.h"
     15 
     16 namespace mozilla {
     17 namespace image {
     18 class RasterImage;
     19 
     20 class nsPNGDecoder : public Decoder {
     21 public:
     22  virtual ~nsPNGDecoder();
     23 
     24  /// @return true if this PNG is a valid ICO resource.
     25  bool IsValidICOResource() const override;
     26 
     27  DecoderType GetType() const override { return DecoderType::PNG; }
     28 
     29 protected:
     30  nsresult InitInternal() override;
     31  nsresult FinishInternal() override;
     32  LexerResult DoDecode(SourceBufferIterator& aIterator,
     33                       IResumable* aOnResume) override;
     34 
     35  Maybe<glean::impl::MemoryDistributionMetric> SpeedMetric() const override;
     36 
     37 private:
     38  friend class DecoderFactory;
     39 
     40  // Decoders should only be instantiated via DecoderFactory.
     41  explicit nsPNGDecoder(RasterImage* aImage);
     42 
     43  /// The information necessary to create a frame.
     44  struct FrameInfo {
     45    UnorientedIntRect mFrameRect;
     46    bool mIsInterlaced;
     47  };
     48 
     49  nsresult CreateFrame(const FrameInfo& aFrameInfo);
     50  void EndImageFrame();
     51 
     52  uint32_t ReadColorProfile(png_structp png_ptr, png_infop info_ptr,
     53                            int color_type, bool* sRGBTag);
     54 
     55  bool HasAlphaChannel() const { return mChannels == 2 || mChannels == 4; }
     56 
     57  enum class TransparencyType { eNone, eAlpha, eFrameRect };
     58 
     59  TransparencyType GetTransparencyType(const UnorientedIntRect& aFrameRect);
     60  void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
     61 
     62  void PostInvalidationIfNeeded();
     63 
     64  void WriteRow(uint8_t* aRow);
     65 
     66  // Convenience methods to make interacting with StreamingLexer from inside
     67  // a libpng callback easier.
     68  void DoTerminate(png_structp aPNGStruct, TerminalState aState);
     69  void DoYield(png_structp aPNGStruct);
     70 
     71  enum class State { PNG_DATA, FINISHED_PNG_DATA };
     72 
     73  LexerTransition<State> ReadPNGData(const char* aData, size_t aLength);
     74  LexerTransition<State> FinishedPNGData();
     75 
     76  StreamingLexer<State> mLexer;
     77 
     78  // The next lexer state transition. We need to store it here because we can't
     79  // directly return arbitrary values from libpng callbacks.
     80  LexerTransition<State> mNextTransition;
     81 
     82  // We yield to the caller every time we finish decoding a frame. When this
     83  // happens, we need to allocate the next frame after returning from the yield.
     84  // |mNextFrameInfo| is used to store the information needed to allocate the
     85  // next frame.
     86  Maybe<FrameInfo> mNextFrameInfo;
     87 
     88  // The length of the last chunk of data passed to ReadPNGData(). We use this
     89  // to arrange to arrive back at the correct spot in the data after yielding.
     90  size_t mLastChunkLength;
     91 
     92 public:
     93  png_structp mPNG;
     94  png_infop mInfo;
     95  UnorientedIntRect mFrameRect;
     96  uint8_t* mCMSLine;
     97  uint8_t* interlacebuf;
     98  gfx::SurfaceFormat mFormat;
     99 
    100  uint8_t mChannels;
    101  uint8_t mPass;
    102  bool mFrameIsHidden;
    103  bool mDisablePremultipliedAlpha;
    104  bool mGotInfoCallback;
    105  bool mUsePipeTransform;
    106  bool mErrorIsRecoverable;
    107 
    108  struct AnimFrameInfo {
    109    AnimFrameInfo();
    110 #ifdef PNG_APNG_SUPPORTED
    111    AnimFrameInfo(png_structp aPNG, png_infop aInfo);
    112 #endif
    113 
    114    DisposalMethod mDispose;
    115    BlendMethod mBlend;
    116    int32_t mTimeout;
    117  };
    118 
    119  AnimFrameInfo mAnimInfo;
    120 
    121  SurfacePipe mPipe;  /// The SurfacePipe used to write to the output surface.
    122 
    123  // The number of frames we've finished.
    124  uint32_t mNumFrames;
    125 
    126  // libpng callbacks
    127  // We put these in the class so that they can access protected members.
    128  static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
    129  static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
    130                                  png_uint_32 row_num, int pass);
    131 #ifdef PNG_APNG_SUPPORTED
    132  static void PNGAPI frame_info_callback(png_structp png_ptr,
    133                                         png_uint_32 frame_num);
    134 #endif
    135  static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
    136  static void PNGAPI error_callback(png_structp png_ptr,
    137                                    png_const_charp error_msg);
    138  static void PNGAPI warning_callback(png_structp png_ptr,
    139                                      png_const_charp warning_msg);
    140 
    141  // This is defined in the PNG spec as an invariant. We use it to
    142  // do manual validation without libpng.
    143  static const uint8_t pngSignatureBytes[];
    144 };
    145 
    146 }  // namespace image
    147 }  // namespace mozilla
    148 
    149 #endif  // mozilla_image_decoders_nsPNGDecoder_h