nsPNGDecoder.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. #ifndef mozilla_image_decoders_nsPNGDecoder_h
  7. #define mozilla_image_decoders_nsPNGDecoder_h
  8. #include "Decoder.h"
  9. #include "png.h"
  10. #include "qcms.h"
  11. #include "StreamingLexer.h"
  12. #include "SurfacePipe.h"
  13. namespace mozilla {
  14. namespace image {
  15. class RasterImage;
  16. class nsPNGDecoder : public Decoder
  17. {
  18. public:
  19. virtual ~nsPNGDecoder();
  20. /// @return true if this PNG is a valid ICO resource.
  21. bool IsValidICO() const;
  22. protected:
  23. nsresult InitInternal() override;
  24. LexerResult DoDecode(SourceBufferIterator& aIterator,
  25. IResumable* aOnResume) override;
  26. Maybe<Telemetry::ID> SpeedHistogram() const override;
  27. private:
  28. friend class DecoderFactory;
  29. // Decoders should only be instantiated via DecoderFactory.
  30. explicit nsPNGDecoder(RasterImage* aImage);
  31. /// The information necessary to create a frame.
  32. struct FrameInfo
  33. {
  34. gfx::SurfaceFormat mFormat;
  35. gfx::IntRect mFrameRect;
  36. bool mIsInterlaced;
  37. };
  38. nsresult CreateFrame(const FrameInfo& aFrameInfo);
  39. void EndImageFrame();
  40. enum class TransparencyType
  41. {
  42. eNone,
  43. eAlpha,
  44. eFrameRect
  45. };
  46. TransparencyType GetTransparencyType(gfx::SurfaceFormat aFormat,
  47. const gfx::IntRect& aFrameRect);
  48. void PostHasTransparencyIfNeeded(TransparencyType aTransparencyType);
  49. void PostInvalidationIfNeeded();
  50. void WriteRow(uint8_t* aRow);
  51. // Convenience methods to make interacting with StreamingLexer from inside
  52. // a libpng callback easier.
  53. void DoTerminate(png_structp aPNGStruct, TerminalState aState);
  54. void DoYield(png_structp aPNGStruct);
  55. enum class State
  56. {
  57. PNG_DATA,
  58. FINISHED_PNG_DATA
  59. };
  60. LexerTransition<State> ReadPNGData(const char* aData, size_t aLength);
  61. LexerTransition<State> FinishedPNGData();
  62. StreamingLexer<State> mLexer;
  63. // The next lexer state transition. We need to store it here because we can't
  64. // directly return arbitrary values from libpng callbacks.
  65. LexerTransition<State> mNextTransition;
  66. // We yield to the caller every time we finish decoding a frame. When this
  67. // happens, we need to allocate the next frame after returning from the yield.
  68. // |mNextFrameInfo| is used to store the information needed to allocate the
  69. // next frame.
  70. Maybe<FrameInfo> mNextFrameInfo;
  71. // The length of the last chunk of data passed to ReadPNGData(). We use this
  72. // to arrange to arrive back at the correct spot in the data after yielding.
  73. size_t mLastChunkLength;
  74. public:
  75. png_structp mPNG;
  76. png_infop mInfo;
  77. nsIntRect mFrameRect;
  78. uint8_t* mCMSLine;
  79. uint8_t* interlacebuf;
  80. qcms_profile* mInProfile;
  81. qcms_transform* mTransform;
  82. gfx::SurfaceFormat format;
  83. // whether CMS or premultiplied alpha are forced off
  84. uint32_t mCMSMode;
  85. uint8_t mChannels;
  86. uint8_t mPass;
  87. bool mFrameIsHidden;
  88. bool mDisablePremultipliedAlpha;
  89. struct AnimFrameInfo
  90. {
  91. AnimFrameInfo();
  92. #ifdef PNG_APNG_SUPPORTED
  93. AnimFrameInfo(png_structp aPNG, png_infop aInfo);
  94. #endif
  95. DisposalMethod mDispose;
  96. BlendMethod mBlend;
  97. int32_t mTimeout;
  98. };
  99. AnimFrameInfo mAnimInfo;
  100. SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface.
  101. // The number of frames we've finished.
  102. uint32_t mNumFrames;
  103. // libpng callbacks
  104. // We put these in the class so that they can access protected members.
  105. static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
  106. static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
  107. png_uint_32 row_num, int pass);
  108. #ifdef PNG_APNG_SUPPORTED
  109. static void PNGAPI frame_info_callback(png_structp png_ptr,
  110. png_uint_32 frame_num);
  111. #endif
  112. static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
  113. static void PNGAPI error_callback(png_structp png_ptr,
  114. png_const_charp error_msg);
  115. static void PNGAPI warning_callback(png_structp png_ptr,
  116. png_const_charp warning_msg);
  117. // This is defined in the PNG spec as an invariant. We use it to
  118. // do manual validation without libpng.
  119. static const uint8_t pngSignatureBytes[];
  120. };
  121. } // namespace image
  122. } // namespace mozilla
  123. #endif // mozilla_image_decoders_nsPNGDecoder_h