2001-11-03 10:10:51 +03:00
|
|
|
/* vim:set tw=80 expandtab softtabstop=4 ts=4 sw=4: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2001-11-03 10:10:51 +03:00
|
|
|
|
|
|
|
|
2015-04-06 02:22:00 +03:00
|
|
|
#ifndef mozilla_image_decoders_nsICODecoder_h
|
|
|
|
#define mozilla_image_decoders_nsICODecoder_h
|
2001-11-03 10:10:51 +03:00
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
#include "StreamingLexer.h"
|
2010-08-23 06:30:46 +04:00
|
|
|
#include "Decoder.h"
|
2014-11-27 00:22:10 +03:00
|
|
|
#include "imgFrame.h"
|
2016-07-03 08:21:00 +03:00
|
|
|
#include "mozilla/gfx/2D.h"
|
2001-11-03 10:10:51 +03:00
|
|
|
#include "nsBMPDecoder.h"
|
2011-08-26 00:09:01 +04:00
|
|
|
#include "nsPNGDecoder.h"
|
2011-08-26 00:09:05 +04:00
|
|
|
#include "ICOFileHeaders.h"
|
2001-11-03 10:10:51 +03:00
|
|
|
|
2010-08-14 08:09:49 +04:00
|
|
|
namespace mozilla {
|
2012-01-06 20:02:27 +04:00
|
|
|
namespace image {
|
2010-08-23 06:30:46 +04:00
|
|
|
|
2010-08-14 08:09:49 +04:00
|
|
|
class RasterImage;
|
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
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,
|
2015-09-22 05:52:31 +03:00
|
|
|
FINISH_MASK,
|
2015-09-19 09:12:30 +03:00
|
|
|
SKIP_MASK,
|
|
|
|
FINISHED_RESOURCE
|
|
|
|
};
|
|
|
|
|
2010-08-23 06:30:46 +04:00
|
|
|
class nsICODecoder : public Decoder
|
2001-11-03 10:10:51 +03:00
|
|
|
{
|
|
|
|
public:
|
2015-09-19 09:12:30 +03:00
|
|
|
virtual ~nsICODecoder() { }
|
2015-09-18 20:54:40 +03:00
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
/// @return the width of the icon directory entry @aEntry.
|
|
|
|
static uint32_t GetRealWidth(const IconDirEntry& aEntry)
|
2011-09-22 17:43:13 +04:00
|
|
|
{
|
2015-09-19 09:12:30 +03:00
|
|
|
return aEntry.mWidth == 0 ? 256 : aEntry.mWidth;
|
2011-09-22 17:43:13 +04:00
|
|
|
}
|
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
/// @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)
|
2011-09-22 17:43:13 +04:00
|
|
|
{
|
2015-09-19 09:12:30 +03:00
|
|
|
return aEntry.mHeight == 0 ? 256 : aEntry.mHeight;
|
2011-09-22 17:43:13 +04:00
|
|
|
}
|
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
/// @return the height of the selected directory entry (mDirEntry).
|
|
|
|
uint32_t GetRealHeight() const { return GetRealHeight(mDirEntry); }
|
|
|
|
|
2015-09-19 23:34:14 +03:00
|
|
|
/// @return the size of the selected directory entry (mDirEntry).
|
|
|
|
gfx::IntSize GetRealSize() const
|
2015-07-31 17:29:03 +03:00
|
|
|
{
|
2015-09-19 23:34:14 +03:00
|
|
|
return gfx::IntSize(GetRealWidth(), GetRealHeight());
|
2015-07-31 17:29:03 +03:00
|
|
|
}
|
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
/// @return The offset from the beginning of the ICO to the first resource.
|
|
|
|
size_t FirstResourceOffset() const;
|
|
|
|
|
2016-07-16 08:27:12 +03:00
|
|
|
LexerResult DoDecode(SourceBufferIterator& aIterator,
|
|
|
|
IResumable* aOnResume) override;
|
2016-07-11 10:38:54 +03:00
|
|
|
nsresult FinishInternal() override;
|
|
|
|
nsresult FinishWithErrorInternal() override;
|
2015-01-08 11:04:31 +03:00
|
|
|
|
2001-11-03 10:10:51 +03:00
|
|
|
private:
|
2015-07-23 08:39:56 +03:00
|
|
|
friend class DecoderFactory;
|
|
|
|
|
|
|
|
// Decoders should only be instantiated via DecoderFactory.
|
|
|
|
explicit nsICODecoder(RasterImage* aImage);
|
|
|
|
|
2012-05-08 16:38:43 +04:00
|
|
|
// Writes to the contained decoder and sets the appropriate errors
|
|
|
|
// Returns true if there are no errors.
|
2015-01-08 11:04:31 +03:00
|
|
|
bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount);
|
2012-05-08 16:38:43 +04:00
|
|
|
|
2015-07-11 05:26:15 +03:00
|
|
|
// Gets decoder state from the contained decoder so it's visible externally.
|
2016-07-11 10:38:54 +03:00
|
|
|
nsresult GetFinalStateFromContainedDecoder();
|
2015-07-11 05:26:15 +03:00
|
|
|
|
2016-06-22 03:56:24 +03:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2011-08-26 00:09:01 +04:00
|
|
|
// Obtains the number of colors from the BPP, mBPP must be filled in
|
2012-08-22 19:56:38 +04:00
|
|
|
uint16_t GetNumColors();
|
|
|
|
|
2015-09-19 09:12:30 +03:00
|
|
|
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);
|
2015-09-22 05:52:31 +03:00
|
|
|
LexerTransition<ICOState> FinishMask();
|
2015-09-19 23:34:06 +03:00
|
|
|
LexerTransition<ICOState> FinishResource();
|
2015-09-19 09:12:30 +03:00
|
|
|
|
|
|
|
StreamingLexer<ICOState, 32> mLexer; // The lexer.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Decoder> mContainedDecoder; // Either a BMP or PNG decoder.
|
2016-07-03 06:20:55 +03:00
|
|
|
RefPtr<SourceBuffer> mContainedSourceBuffer; // SourceBuffer for mContainedDecoder.
|
2015-09-22 05:52:31 +03:00
|
|
|
UniquePtr<uint8_t[]> mMaskBuffer; // A temporary buffer for the alpha mask.
|
2015-10-16 01:43:31 +03:00
|
|
|
char mBIHraw[bmp::InfoHeaderLength::WIN_ICO]; // The bitmap information header.
|
2015-09-19 09:12:30 +03:00
|
|
|
IconDirEntry mDirEntry; // The dir entry for the selected resource.
|
2016-06-30 20:24:27 +03:00
|
|
|
gfx::IntSize mBiggestResourceSize; // Used to select the intrinsic size.
|
|
|
|
gfx::IntSize mBiggestResourceHotSpot; // Used to select the intrinsic size.
|
2015-09-19 23:34:14 +03:00
|
|
|
uint16_t mBiggestResourceColorDepth; // Used to select the intrinsic size.
|
2015-09-19 09:12:30 +03:00
|
|
|
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?
|
2015-09-22 05:52:31 +03:00
|
|
|
bool mHasMaskAlpha; // Did the BMP alpha mask have any transparency?
|
2001-11-03 10:10:51 +03:00
|
|
|
};
|
|
|
|
|
2012-01-06 20:02:27 +04:00
|
|
|
} // namespace image
|
2010-08-23 06:30:46 +04:00
|
|
|
} // namespace mozilla
|
2001-11-03 10:10:51 +03:00
|
|
|
|
2015-04-06 02:22:00 +03:00
|
|
|
#endif // mozilla_image_decoders_nsICODecoder_h
|