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 | |
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')
-rw-r--r-- | image/DecoderFactory.cpp | 7 | ||||
-rw-r--r-- | image/DecoderFactory.h | 1 | ||||
-rw-r--r-- | image/IDecodingTask.cpp | 15 | ||||
-rw-r--r-- | image/IDecodingTask.h | 8 | ||||
-rw-r--r-- | image/Image.h | 2 | ||||
-rw-r--r-- | image/ImageOps.cpp | 2 | ||||
-rw-r--r-- | image/SourceBuffer.cpp | 14 | ||||
-rw-r--r-- | image/SourceBuffer.h | 7 | ||||
-rw-r--r-- | image/VectorImage.cpp | 9 | ||||
-rw-r--r-- | image/VectorImage.h | 2 | ||||
-rw-r--r-- | image/decoders/nsBMPDecoder.cpp | 40 | ||||
-rw-r--r-- | image/decoders/nsBMPDecoder.h | 9 | ||||
-rw-r--r-- | image/decoders/nsWebPDecoder.cpp | 4 |
13 files changed, 89 insertions, 31 deletions
diff --git a/image/DecoderFactory.cpp b/image/DecoderFactory.cpp index 2085fb7c4..dffe4dc21 100644 --- a/image/DecoderFactory.cpp +++ b/image/DecoderFactory.cpp @@ -58,6 +58,10 @@ DecoderFactory::GetDecoderType(const char* aMimeType) } else if (!strcmp(aMimeType, IMAGE_BMP_MS)) { type = DecoderType::BMP; + // BMP_CLIPBOARD + } else if (!strcmp(aMimeType, IMAGE_BMP_MS_CLIPBOARD)) { + type = DecoderType::BMP_CLIPBOARD; + // ICO } else if (!strcmp(aMimeType, IMAGE_ICO)) { type = DecoderType::ICO; @@ -100,6 +104,9 @@ DecoderFactory::GetDecoder(DecoderType aType, case DecoderType::BMP: decoder = new nsBMPDecoder(aImage); break; + case DecoderType::BMP_CLIPBOARD: + decoder = new nsBMPDecoder(aImage, /* aForClipboard */ true); + break; case DecoderType::ICO: decoder = new nsICODecoder(aImage); break; diff --git a/image/DecoderFactory.h b/image/DecoderFactory.h index f8cf64cc6..5638789ff 100644 --- a/image/DecoderFactory.h +++ b/image/DecoderFactory.h @@ -34,6 +34,7 @@ enum class DecoderType GIF, JPEG, BMP, + BMP_CLIPBOARD, ICO, ICON, WEBP, diff --git a/image/IDecodingTask.cpp b/image/IDecodingTask.cpp index a067e7a7d..6e2f039be 100644 --- a/image/IDecodingTask.cpp +++ b/image/IDecodingTask.cpp @@ -142,8 +142,10 @@ MetadataDecodingTask::Run() // AnonymousDecodingTask implementation. /////////////////////////////////////////////////////////////////////////////// -AnonymousDecodingTask::AnonymousDecodingTask(NotNull<Decoder*> aDecoder) +AnonymousDecodingTask::AnonymousDecodingTask(NotNull<Decoder*> aDecoder, + bool aResumable) : mDecoder(aDecoder) + , mResumable(aResumable) { } void @@ -168,5 +170,16 @@ AnonymousDecodingTask::Run() } } +void +AnonymousDecodingTask::Resume() +{ + // Anonymous decoders normally get all their data at once. We have some situations + // where they don't. If explicitly requested, resuming should be supported. + if (mResumable) { + RefPtr<AnonymousDecodingTask> self(this); + NS_DispatchToMainThread(NS_NewRunnableFunction([self]() -> void { self->Run(); })); + } +} + } // namespace image } // namespace mozilla diff --git a/image/IDecodingTask.h b/image/IDecodingTask.h index 196ce5fdc..3cbab5006 100644 --- a/image/IDecodingTask.h +++ b/image/IDecodingTask.h @@ -102,22 +102,20 @@ class AnonymousDecodingTask final : public IDecodingTask public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnonymousDecodingTask, override) - explicit AnonymousDecodingTask(NotNull<Decoder*> aDecoder); + explicit AnonymousDecodingTask(NotNull<Decoder*> aDecoder, bool aResumable); void Run() override; bool ShouldPreferSyncRun() const override { return true; } TaskPriority Priority() const override { return TaskPriority::eLow; } - // Anonymous decoders normally get all their data at once. We have tests where - // they don't; in these situations, the test re-runs them manually. So no - // matter what, we don't want to resume by posting a task to the DecodePool. - void Resume() override { } + void Resume() override; private: virtual ~AnonymousDecodingTask() { } NotNull<RefPtr<Decoder>> mDecoder; + bool mResumable; }; } // namespace image diff --git a/image/Image.h b/image/Image.h index bcabd1cc7..98c5e8ca5 100644 --- a/image/Image.h +++ b/image/Image.h @@ -220,8 +220,6 @@ public: virtual void SetHasError() = 0; virtual ImageURL* GetURI() = 0; - - virtual void ReportUseCounters() { } }; class ImageResource : public Image diff --git a/image/ImageOps.cpp b/image/ImageOps.cpp index addee7f15..ddd2f200e 100644 --- a/image/ImageOps.cpp +++ b/image/ImageOps.cpp @@ -126,7 +126,7 @@ ImageOps::DecodeToSurface(nsIInputStream* aInputStream, } // Run the decoder synchronously. - RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder)); + RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false); task->Run(); if (!decoder->GetDecodeDone() || decoder->HasError()) { return nullptr; diff --git a/image/SourceBuffer.cpp b/image/SourceBuffer.cpp index de0719d45..de066e29f 100644 --- a/image/SourceBuffer.cpp +++ b/image/SourceBuffer.cpp @@ -451,10 +451,18 @@ SourceBuffer::AppendFromInputStream(nsIInputStream* aInputStream, uint32_t bytesRead; nsresult rv = aInputStream->ReadSegments(AppendToSourceBuffer, this, aCount, &bytesRead); - if (!NS_WARN_IF(NS_FAILED(rv))) { - MOZ_ASSERT(bytesRead == aCount, - "AppendToSourceBuffer should consume everything"); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + if (bytesRead == 0) { + // The loading of the image has been canceled. + return NS_ERROR_FAILURE; } + + MOZ_ASSERT(bytesRead == aCount, + "AppendToSourceBuffer should consume everything"); + return rv; } diff --git a/image/SourceBuffer.h b/image/SourceBuffer.h index 64727e65e..6f2c74d33 100644 --- a/image/SourceBuffer.h +++ b/image/SourceBuffer.h @@ -174,6 +174,13 @@ public: return mState == READY ? mData.mIterating.mNextReadLength : 0; } + /// If we're ready to read, returns whether or not everything available thus + /// far has been in the same contiguous buffer. + bool IsContiguous() const { + MOZ_ASSERT(mState == READY, "Calling IsContiguous() in the wrong state"); + return mState == READY ? mData.mIterating.mChunk == 0 : false; + } + /// @return a count of the chunks we've advanced through. uint32_t ChunkCount() const { return mChunkCount; } diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 1e59b13fa..3028c1c2e 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -1337,15 +1337,6 @@ VectorImage::PropagateUseCounters(nsIDocument* aParentDocument) } } -void -VectorImage::ReportUseCounters() -{ - nsIDocument* doc = mSVGDocumentWrapper->GetDocument(); - if (doc) { - static_cast<nsDocument*>(doc)->ReportUseCounters(); - } -} - nsIntSize VectorImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, diff --git a/image/VectorImage.h b/image/VectorImage.h index e19aa939f..bd4d393ed 100644 --- a/image/VectorImage.h +++ b/image/VectorImage.h @@ -68,8 +68,6 @@ public: void OnSVGDocumentLoaded(); void OnSVGDocumentError(); - virtual void ReportUseCounters() override; - protected: explicit VectorImage(ImageURL* aURI = nullptr); virtual ~VectorImage(); 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 |