summaryrefslogtreecommitdiffstats
path: root/image/decoders/nsICODecoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'image/decoders/nsICODecoder.h')
-rw-r--r--image/decoders/nsICODecoder.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/image/decoders/nsICODecoder.h b/image/decoders/nsICODecoder.h
new file mode 100644
index 000000000..46e1377aa
--- /dev/null
+++ b/image/decoders/nsICODecoder.h
@@ -0,0 +1,137 @@
+/* vim:set tw=80 expandtab softtabstop=4 ts=4 sw=4: */
+/* 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 mozilla_image_decoders_nsICODecoder_h
+#define mozilla_image_decoders_nsICODecoder_h
+
+#include "StreamingLexer.h"
+#include "Decoder.h"
+#include "imgFrame.h"
+#include "mozilla/gfx/2D.h"
+#include "nsBMPDecoder.h"
+#include "nsPNGDecoder.h"
+#include "ICOFileHeaders.h"
+
+namespace mozilla {
+namespace image {
+
+class RasterImage;
+
+enum class ICOState
+{
+ HEADER,
+ DIR_ENTRY,
+ SKIP_TO_RESOURCE,
+ FOUND_RESOURCE,
+ SNIFF_RESOURCE,
+ READ_PNG,
+ READ_BIH,
+ READ_BMP,
+ PREPARE_FOR_MASK,
+ READ_MASK_ROW,
+ FINISH_MASK,
+ SKIP_MASK,
+ FINISHED_RESOURCE
+};
+
+class nsICODecoder : public Decoder
+{
+public:
+ virtual ~nsICODecoder() { }
+
+ /// @return the width of the icon directory entry @aEntry.
+ static uint32_t GetRealWidth(const IconDirEntry& aEntry)
+ {
+ return aEntry.mWidth == 0 ? 256 : aEntry.mWidth;
+ }
+
+ /// @return the width of the selected directory entry (mDirEntry).
+ uint32_t GetRealWidth() const { return GetRealWidth(mDirEntry); }
+
+ /// @return the height of the icon directory entry @aEntry.
+ static uint32_t GetRealHeight(const IconDirEntry& aEntry)
+ {
+ return aEntry.mHeight == 0 ? 256 : aEntry.mHeight;
+ }
+
+ /// @return the height of the selected directory entry (mDirEntry).
+ uint32_t GetRealHeight() const { return GetRealHeight(mDirEntry); }
+
+ /// @return the size of the selected directory entry (mDirEntry).
+ gfx::IntSize GetRealSize() const
+ {
+ return gfx::IntSize(GetRealWidth(), GetRealHeight());
+ }
+
+ /// @return The offset from the beginning of the ICO to the first resource.
+ size_t FirstResourceOffset() const;
+
+ LexerResult DoDecode(SourceBufferIterator& aIterator,
+ IResumable* aOnResume) override;
+ nsresult FinishInternal() override;
+ nsresult FinishWithErrorInternal() override;
+
+private:
+ friend class DecoderFactory;
+
+ // Decoders should only be instantiated via DecoderFactory.
+ explicit nsICODecoder(RasterImage* aImage);
+
+ // Writes to the contained decoder and sets the appropriate errors
+ // Returns true if there are no errors.
+ bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount);
+
+ // Gets decoder state from the contained decoder so it's visible externally.
+ nsresult GetFinalStateFromContainedDecoder();
+
+ /**
+ * Verifies that the width and height values in @aBIH are valid and match the
+ * values we read from the ICO directory entry. If everything looks OK, the
+ * height value in @aBIH is updated to compensate for the AND mask, which the
+ * underlying BMP decoder doesn't know about.
+ *
+ * @return true if the width and height values in @aBIH are valid and correct.
+ */
+ bool CheckAndFixBitmapSize(int8_t* aBIH);
+
+ // Obtains the number of colors from the BPP, mBPP must be filled in
+ uint16_t GetNumColors();
+
+ LexerTransition<ICOState> ReadHeader(const char* aData);
+ LexerTransition<ICOState> ReadDirEntry(const char* aData);
+ LexerTransition<ICOState> SniffResource(const char* aData);
+ LexerTransition<ICOState> ReadPNG(const char* aData, uint32_t aLen);
+ LexerTransition<ICOState> ReadBIH(const char* aData);
+ LexerTransition<ICOState> ReadBMP(const char* aData, uint32_t aLen);
+ LexerTransition<ICOState> PrepareForMask();
+ LexerTransition<ICOState> ReadMaskRow(const char* aData);
+ LexerTransition<ICOState> FinishMask();
+ LexerTransition<ICOState> FinishResource();
+
+ StreamingLexer<ICOState, 32> mLexer; // The lexer.
+ RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
+ RefPtr<SourceBuffer> mContainedSourceBuffer; // SourceBuffer for mContainedDecoder.
+ UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
+ char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
+ IconDirEntry mDirEntry; // The dir entry for the selected resource.
+ gfx::IntSize mBiggestResourceSize; // Used to select the intrinsic size.
+ gfx::IntSize mBiggestResourceHotSpot; // Used to select the intrinsic size.
+ uint16_t mBiggestResourceColorDepth; // Used to select the intrinsic size.
+ int32_t mBestResourceDelta; // Used to select the best resource.
+ uint16_t mBestResourceColorDepth; // Used to select the best resource.
+ uint16_t mNumIcons; // Stores the number of icons in the ICO file.
+ uint16_t mCurrIcon; // Stores the current dir entry index we are processing.
+ uint16_t mBPP; // The BPP of the resource we're decoding.
+ uint32_t mMaskRowSize; // The size in bytes of each row in the BMP alpha mask.
+ uint32_t mCurrMaskLine; // The line of the BMP alpha mask we're processing.
+ bool mIsCursor; // Is this ICO a cursor?
+ bool mHasMaskAlpha; // Did the BMP alpha mask have any transparency?
+};
+
+} // namespace image
+} // namespace mozilla
+
+#endif // mozilla_image_decoders_nsICODecoder_h