diff options
author | Moonchild <mcwerewolf@wolfbeast.com> | 2019-03-13 07:49:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-13 07:49:07 +0100 |
commit | bf0413359245579e9509146d42cd5547e35da695 (patch) | |
tree | 8218d4f60d9eccacbf42df8cb88094a082d401b4 /image/decoders | |
parent | 51b821b3fdc5a7eab2369cb6a6680598a6264b08 (diff) | |
parent | 709bc24e9110eba12f94cfcb8db00a8338ac4098 (diff) | |
download | UXP-bf0413359245579e9509146d42cd5547e35da695.tar UXP-bf0413359245579e9509146d42cd5547e35da695.tar.gz UXP-bf0413359245579e9509146d42cd5547e35da695.tar.lz UXP-bf0413359245579e9509146d42cd5547e35da695.tar.xz UXP-bf0413359245579e9509146d42cd5547e35da695.zip |
Merge pull request #998 from MoonchildProductions/master
Merge master into Sync-weave
Diffstat (limited to 'image/decoders')
-rw-r--r-- | image/decoders/nsBMPDecoder.cpp | 40 | ||||
-rw-r--r-- | image/decoders/nsBMPDecoder.h | 9 | ||||
-rw-r--r-- | image/decoders/nsWebPDecoder.cpp | 4 |
3 files changed, 45 insertions, 8 deletions
diff --git a/image/decoders/nsBMPDecoder.cpp b/image/decoders/nsBMPDecoder.cpp index 42bb3486a..b93eb42b6 100644 --- a/image/decoders/nsBMPDecoder.cpp +++ b/image/decoders/nsBMPDecoder.cpp @@ -66,6 +66,17 @@ // compression, then instead of treating the pixel data as 0RGB it is treated // as ARGB, but only if one or more of the A values are non-zero. // +// Clipboard variants. +// - It's the BMP format used for BMP images captured from the clipboard. +// - It is missing the file header, containing the BM signature and the data +// offset. Instead the data begins after the header. +// - If it uses BITFIELDS compression, then there is always an additional 12 +// bytes of data after the header that must be read. In WinBMPv4+, the masks +// are supposed to be included in the header size, which are the values we use +// for decoding purposes, but there is additional three masks following the +// header which must be skipped to get to the pixel data. +// +// // OS/2 VERSIONS OF THE BMP FORMAT // ------------------------------- // OS2-BMPv1. @@ -168,10 +179,12 @@ static mozilla::LazyLogModule sBMPLog("BMPDecoder"); // The length of the mBIHSize field in the info header. static const uint32_t BIHSIZE_FIELD_LENGTH = 4; -nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength) +nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength, + bool aForClipboard) : Decoder(aImage) , mLexer(Transition::To(aState, aLength), Transition::TerminateSuccess()) , mIsWithinICO(false) + , mIsForClipboard(aForClipboard) , mMayHaveTransparency(false) , mDoesHaveTransparency(false) , mNumColors(0) @@ -185,15 +198,19 @@ nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength) { } -// Constructor for normal BMP files. -nsBMPDecoder::nsBMPDecoder(RasterImage* aImage) - : nsBMPDecoder(aImage, State::FILE_HEADER, FILE_HEADER_LENGTH) +// Constructor for normal BMP files or from the clipboard. +nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, bool aForClipboard) + : nsBMPDecoder(aImage, + aForClipboard ? State::INFO_HEADER_SIZE : State::FILE_HEADER, + aForClipboard ? BIHSIZE_FIELD_LENGTH : FILE_HEADER_LENGTH, + aForClipboard) { } // Constructor used for WinBMPv3-ICO files, which lack a file header. nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset) - : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH) + : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH, + /* aForClipboard */ false) { SetIsWithinICO(); @@ -598,6 +615,13 @@ nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength) // Bitfields are present in the info header, so we can read them // immediately. mBitFields.ReadFromHeader(aData + 36, /* aReadAlpha = */ true); + + // If this came from the clipboard, then we know that even if the header + // explicitly includes the bitfield masks, we need to add an additional + // offset for the start of the RGB data. + if (mIsForClipboard) { + mH.mDataOffset += BitFields::LENGTH; + } } else { // Bitfields are present after the info header, so we will read them in // ReadBitfields(). @@ -712,6 +736,12 @@ nsBMPDecoder::ReadColorTable(const char* aData, size_t aLength) aData += mBytesPerColor; } + // If we are decoding a BMP from the clipboard, we did not know the data + // offset in advance. It is defined as just after the header and color table. + if (mIsForClipboard) { + mH.mDataOffset += mPreGapLength; + } + // We know how many bytes we've read so far (mPreGapLength) and we know the // offset of the pixel data (mH.mDataOffset), so we can determine the length // of the gap (possibly zero) between the color table and the pixel data. diff --git a/image/decoders/nsBMPDecoder.h b/image/decoders/nsBMPDecoder.h index 0cf2af689..4b9568487 100644 --- a/image/decoders/nsBMPDecoder.h +++ b/image/decoders/nsBMPDecoder.h @@ -164,14 +164,14 @@ private: RLE_ABSOLUTE }; - // This is the constructor used for normal BMP images. - explicit nsBMPDecoder(RasterImage* aImage); + // This is the constructor used for normal and clipboard BMP images. + explicit nsBMPDecoder(RasterImage* aImage, bool aForClipboard = false); // This is the constructor used for BMP resources in ICO images. nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset); // Helper constructor called by the other two. - nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength); + nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength, bool aForClipboard); int32_t AbsoluteHeight() const { return abs(mH.mHeight); } @@ -198,6 +198,9 @@ private: // If the BMP is within an ICO file our treatment of it differs slightly. bool mIsWithinICO; + // If the BMP is decoded from the clipboard, we start with a data offset. + bool mIsForClipboard; + bmp::BitFields mBitFields; // Might the image have transparency? Determined from the headers during diff --git a/image/decoders/nsWebPDecoder.cpp b/image/decoders/nsWebPDecoder.cpp index 4f3cc8b2a..3181e3a3a 100644 --- a/image/decoders/nsWebPDecoder.cpp +++ b/image/decoders/nsWebPDecoder.cpp @@ -144,6 +144,10 @@ nsWebPDecoder::UpdateBuffer(SourceBufferIterator& aIterator, switch (aState) { case SourceBufferIterator::READY: + if(!aIterator.IsContiguous()) { + //We need to buffer. This should be rare, but expensive. + break; + } if (!mData) { // For as long as we hold onto an iterator, we know the data pointers // to the chunks cannot change underneath us, so save the pointer to |