nsICODecoder.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* vim:set tw=80 expandtab softtabstop=4 ts=4 sw=4: */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_image_decoders_nsICODecoder_h
  6. #define mozilla_image_decoders_nsICODecoder_h
  7. #include "StreamingLexer.h"
  8. #include "Decoder.h"
  9. #include "imgFrame.h"
  10. #include "mozilla/gfx/2D.h"
  11. #include "nsBMPDecoder.h"
  12. #include "nsPNGDecoder.h"
  13. #include "ICOFileHeaders.h"
  14. namespace mozilla {
  15. namespace image {
  16. class RasterImage;
  17. enum class ICOState
  18. {
  19. HEADER,
  20. DIR_ENTRY,
  21. SKIP_TO_RESOURCE,
  22. FOUND_RESOURCE,
  23. SNIFF_RESOURCE,
  24. READ_PNG,
  25. READ_BIH,
  26. READ_BMP,
  27. PREPARE_FOR_MASK,
  28. READ_MASK_ROW,
  29. FINISH_MASK,
  30. SKIP_MASK,
  31. FINISHED_RESOURCE
  32. };
  33. class nsICODecoder : public Decoder
  34. {
  35. public:
  36. virtual ~nsICODecoder() { }
  37. /// @return the width of the icon directory entry @aEntry.
  38. static uint32_t GetRealWidth(const IconDirEntry& aEntry)
  39. {
  40. return aEntry.mWidth == 0 ? 256 : aEntry.mWidth;
  41. }
  42. /// @return the width of the selected directory entry (mDirEntry).
  43. uint32_t GetRealWidth() const { return GetRealWidth(mDirEntry); }
  44. /// @return the height of the icon directory entry @aEntry.
  45. static uint32_t GetRealHeight(const IconDirEntry& aEntry)
  46. {
  47. return aEntry.mHeight == 0 ? 256 : aEntry.mHeight;
  48. }
  49. /// @return the height of the selected directory entry (mDirEntry).
  50. uint32_t GetRealHeight() const { return GetRealHeight(mDirEntry); }
  51. /// @return the size of the selected directory entry (mDirEntry).
  52. gfx::IntSize GetRealSize() const
  53. {
  54. return gfx::IntSize(GetRealWidth(), GetRealHeight());
  55. }
  56. /// @return The offset from the beginning of the ICO to the first resource.
  57. size_t FirstResourceOffset() const;
  58. LexerResult DoDecode(SourceBufferIterator& aIterator,
  59. IResumable* aOnResume) override;
  60. nsresult FinishInternal() override;
  61. nsresult FinishWithErrorInternal() override;
  62. private:
  63. friend class DecoderFactory;
  64. // Decoders should only be instantiated via DecoderFactory.
  65. explicit nsICODecoder(RasterImage* aImage);
  66. // Writes to the contained decoder and sets the appropriate errors
  67. // Returns true if there are no errors.
  68. bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount);
  69. // Gets decoder state from the contained decoder so it's visible externally.
  70. nsresult GetFinalStateFromContainedDecoder();
  71. /**
  72. * Verifies that the width and height values in @aBIH are valid and match the
  73. * values we read from the ICO directory entry. If everything looks OK, the
  74. * height value in @aBIH is updated to compensate for the AND mask, which the
  75. * underlying BMP decoder doesn't know about.
  76. *
  77. * @return true if the width and height values in @aBIH are valid and correct.
  78. */
  79. bool CheckAndFixBitmapSize(int8_t* aBIH);
  80. // Obtains the number of colors from the BPP, mBPP must be filled in
  81. uint16_t GetNumColors();
  82. LexerTransition<ICOState> ReadHeader(const char* aData);
  83. LexerTransition<ICOState> ReadDirEntry(const char* aData);
  84. LexerTransition<ICOState> SniffResource(const char* aData);
  85. LexerTransition<ICOState> ReadPNG(const char* aData, uint32_t aLen);
  86. LexerTransition<ICOState> ReadBIH(const char* aData);
  87. LexerTransition<ICOState> ReadBMP(const char* aData, uint32_t aLen);
  88. LexerTransition<ICOState> PrepareForMask();
  89. LexerTransition<ICOState> ReadMaskRow(const char* aData);
  90. LexerTransition<ICOState> FinishMask();
  91. LexerTransition<ICOState> FinishResource();
  92. StreamingLexer<ICOState, 32> mLexer; // The lexer.
  93. RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
  94. RefPtr<SourceBuffer> mContainedSourceBuffer; // SourceBuffer for mContainedDecoder.
  95. UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
  96. char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
  97. IconDirEntry mDirEntry; // The dir entry for the selected resource.
  98. gfx::IntSize mBiggestResourceSize; // Used to select the intrinsic size.
  99. gfx::IntSize mBiggestResourceHotSpot; // Used to select the intrinsic size.
  100. uint16_t mBiggestResourceColorDepth; // Used to select the intrinsic size.
  101. int32_t mBestResourceDelta; // Used to select the best resource.
  102. uint16_t mBestResourceColorDepth; // Used to select the best resource.
  103. uint16_t mNumIcons; // Stores the number of icons in the ICO file.
  104. uint16_t mCurrIcon; // Stores the current dir entry index we are processing.
  105. uint16_t mBPP; // The BPP of the resource we're decoding.
  106. uint32_t mMaskRowSize; // The size in bytes of each row in the BMP alpha mask.
  107. uint32_t mCurrMaskLine; // The line of the BMP alpha mask we're processing.
  108. bool mIsCursor; // Is this ICO a cursor?
  109. bool mHasMaskAlpha; // Did the BMP alpha mask have any transparency?
  110. };
  111. } // namespace image
  112. } // namespace mozilla
  113. #endif // mozilla_image_decoders_nsICODecoder_h