[GTK][WPE] ImageDecoders: use SharedBuffer::DataSegment instead of SharedBuffer
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Oct 2019 09:01:02 +0000 (09:01 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Oct 2019 09:01:02 +0000 (09:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202807

Reviewed by Adrian Perez de Castro.

Because SharedBuffer::DataSegment is ThreadSafeRefCounted.

* platform/image-decoders/ScalableImageDecoder.h:
* platform/image-decoders/bmp/BMPImageDecoder.cpp:
(WebCore::BMPImageDecoder::setData):
(WebCore::BMPImageDecoder::decodeHelper):
* platform/image-decoders/bmp/BMPImageDecoder.h:
* platform/image-decoders/bmp/BMPImageReader.h:
(WebCore::BMPImageReader::readUint16):
(WebCore::BMPImageReader::readUint32):
(WebCore::BMPImageReader::setData):
(WebCore::BMPImageReader::readUint16 const):
(WebCore::BMPImageReader::readUint32 const):
* platform/image-decoders/gif/GIFImageDecoder.cpp:
(WebCore::GIFImageDecoder::setData):
(WebCore::GIFImageDecoder::decode):
* platform/image-decoders/gif/GIFImageReader.h:
(GIFImageReader::setData):
* platform/image-decoders/ico/ICOImageDecoder.cpp:
(WebCore::ICOImageDecoder::setData):
(WebCore::ICOImageDecoder::decodeAtIndex):
* platform/image-decoders/ico/ICOImageDecoder.h:
* platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
(WebCore::JPEGImageReader::decode):
* platform/image-decoders/jpeg2000/JPEG2000ImageDecoder.cpp:
(WebCore::JPEG2000ImageDecoder::decode):
* platform/image-decoders/png/PNGImageDecoder.cpp:
(WebCore::PNGImageReader::decode):
* platform/image-decoders/webp/WEBPImageDecoder.cpp:
(WebCore::WEBPImageDecoder::decode):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251836 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/image-decoders/ScalableImageDecoder.h
Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h
Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
Source/WebCore/platform/image-decoders/gif/GIFImageReader.h
Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
Source/WebCore/platform/image-decoders/jpeg2000/JPEG2000ImageDecoder.cpp
Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp

index 4bcbae7..40bbf91 100644 (file)
@@ -1,3 +1,41 @@
+2019-10-29  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [GTK][WPE] ImageDecoders: use SharedBuffer::DataSegment instead of SharedBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=202807
+
+        Reviewed by Adrian Perez de Castro.
+
+        Because SharedBuffer::DataSegment is ThreadSafeRefCounted.
+
+        * platform/image-decoders/ScalableImageDecoder.h:
+        * platform/image-decoders/bmp/BMPImageDecoder.cpp:
+        (WebCore::BMPImageDecoder::setData):
+        (WebCore::BMPImageDecoder::decodeHelper):
+        * platform/image-decoders/bmp/BMPImageDecoder.h:
+        * platform/image-decoders/bmp/BMPImageReader.h:
+        (WebCore::BMPImageReader::readUint16):
+        (WebCore::BMPImageReader::readUint32):
+        (WebCore::BMPImageReader::setData):
+        (WebCore::BMPImageReader::readUint16 const):
+        (WebCore::BMPImageReader::readUint32 const):
+        * platform/image-decoders/gif/GIFImageDecoder.cpp:
+        (WebCore::GIFImageDecoder::setData):
+        (WebCore::GIFImageDecoder::decode):
+        * platform/image-decoders/gif/GIFImageReader.h:
+        (GIFImageReader::setData):
+        * platform/image-decoders/ico/ICOImageDecoder.cpp:
+        (WebCore::ICOImageDecoder::setData):
+        (WebCore::ICOImageDecoder::decodeAtIndex):
+        * platform/image-decoders/ico/ICOImageDecoder.h:
+        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
+        (WebCore::JPEGImageReader::decode):
+        * platform/image-decoders/jpeg2000/JPEG2000ImageDecoder.cpp:
+        (WebCore::JPEG2000ImageDecoder::decode):
+        * platform/image-decoders/png/PNGImageDecoder.cpp:
+        (WebCore::PNGImageReader::decode):
+        * platform/image-decoders/webp/WEBPImageDecoder.cpp:
+        (WebCore::WEBPImageDecoder::decode):
+
 2019-10-30  Peng Liu  <peng.liu6@apple.com>
 
         [Picture-in-Picture Web API] Enable the support for iOS
index 99729ba..ed349f8 100644 (file)
@@ -76,7 +76,10 @@ public:
         if (m_encodedDataStatus == EncodedDataStatus::Error)
             return;
 
-        m_data = &data;
+        if (data.data()) {
+            // SharedBuffer::data() combines all segments into one in case there's more than one.
+            m_data = data.begin()->segment.copyRef();
+        }
         if (m_encodedDataStatus == EncodedDataStatus::TypeAvailable) {
             m_decodingSizeFromSetData = true;
             tryDecodeSize(allDataReceived);
@@ -192,7 +195,7 @@ public:
     Optional<IntPoint> hotSpot() const override { return WTF::nullopt; }
 
 protected:
-    RefPtr<SharedBuffer> m_data; // The encoded data.
+    RefPtr<SharedBuffer::DataSegment> m_data;
     Vector<ScalableImageDecoderFrame, 1> m_frameBufferCache;
     mutable Lock m_mutex;
     bool m_premultiplyAlpha;
index 78697eb..72769a6 100644 (file)
@@ -53,7 +53,7 @@ void BMPImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
 
     ScalableImageDecoder::setData(data, allDataReceived);
     if (m_reader)
-        m_reader->setData(&data);
+        m_reader->setData(*m_data);
 }
 
 ScalableImageDecoderFrame* BMPImageDecoder::frameBufferAtIndex(size_t index)
@@ -99,7 +99,7 @@ bool BMPImageDecoder::decodeHelper(bool onlySize)
 
     if (!m_reader) {
         m_reader = makeUnique<BMPImageReader>(this, m_decodedOffset, imgDataOffset, false);
-        m_reader->setData(m_data.get());
+        m_reader->setData(*m_data);
     }
 
     if (!m_frameBufferCache.isEmpty())
index 14a4feb..c7c7ca8 100644 (file)
@@ -57,7 +57,7 @@ private:
 
     inline uint32_t readUint32(int offset) const
     {
-        return BMPImageReader::readUint32(m_data.get(), m_decodedOffset + offset);
+        return BMPImageReader::readUint32(*m_data, m_decodedOffset + offset);
     }
 
     // Decodes the image. If |onlySize| is true, stops decoding after
index 923c6d9..4844f38 100644 (file)
@@ -42,20 +42,20 @@ class BMPImageReader {
 public:
     // Read a value from |data[offset]|, converting from little to native
     // endianness.
-    static inline uint16_t readUint16(SharedBuffer* data, int offset)
+    static inline uint16_t readUint16(const SharedBuffer::DataSegment& data, int offset)
     {
         uint16_t result;
-        memcpy(&result, &data->data()[offset], 2);
+        memcpy(&result, &data.data()[offset], 2);
 #if CPU(BIG_ENDIAN)
         result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
 #endif
         return result;
     }
 
-    static inline uint32_t readUint32(SharedBuffer* data, int offset)
+    static inline uint32_t readUint32(const SharedBuffer::DataSegment& data, int offset)
     {
         uint32_t result;
-        memcpy(&result, &data->data()[offset], 4);
+        memcpy(&result, &data.data()[offset], 4);
 #if CPU(BIG_ENDIAN)
         result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
 #endif
@@ -69,7 +69,7 @@ public:
     BMPImageReader(ScalableImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool usesAndMask);
 
     void setBuffer(ScalableImageDecoderFrame* buffer) { m_buffer = buffer; }
-    void setData(SharedBuffer* data) { m_data = data; }
+    void setData(SharedBuffer::DataSegment& data) { m_data = &data; }
 
     // Does the actual decoding. If |onlySize| is true, decoding only
     // progresses as far as necessary to get the image size. Returns
@@ -121,12 +121,12 @@ private:
 
     inline uint16_t readUint16(int offset) const
     {
-        return readUint16(m_data.get(), m_decodedOffset + offset);
+        return readUint16(*m_data, m_decodedOffset + offset);
     }
 
     inline uint32_t readUint32(int offset) const
     {
-        return readUint32(m_data.get(), m_decodedOffset + offset);
+        return readUint32(*m_data, m_decodedOffset + offset);
     }
 
     // Determines the size of the BMP info header. Returns true if the size
@@ -272,7 +272,7 @@ private:
     ScalableImageDecoderFrame* m_buffer;
 
     // The file to decode.
-    RefPtr<SharedBuffer> m_data;
+    RefPtr<SharedBuffer::DataSegment> m_data;
 
     // An index into |m_data| representing how much we've already decoded.
     size_t m_decodedOffset;
index d017a59..e6abe0d 100644 (file)
@@ -45,7 +45,7 @@ void GIFImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
 
     ScalableImageDecoder::setData(data, allDataReceived);
     if (m_reader)
-        m_reader->setData(&data);
+        m_reader->setData(*m_data);
 }
 
 bool GIFImageDecoder::setSize(const IntSize& size)
@@ -328,7 +328,7 @@ void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query, bool allDataR
 
     if (!m_reader) {
         m_reader = makeUnique<GIFImageReader>(this);
-        m_reader->setData(m_data.get());
+        m_reader->setData(*m_data);
     }
 
     if (query == GIFSizeQuery) {
index d0fc58a..427646c 100644 (file)
@@ -237,7 +237,7 @@ public:
     {
     }
 
-    void setData(WebCore::SharedBuffer* data) { m_data = data; }
+    void setData(WebCore::SharedBuffer::DataSegment& data) { m_data = &data; }
     // FIXME: haltAtFrame should be size_t.
     bool decode(WebCore::GIFImageDecoder::GIFQuery, unsigned haltAtFrame);
 
@@ -316,6 +316,6 @@ private:
     Vector<std::unique_ptr<GIFFrameContext> > m_frames;
     size_t m_currentDecodingFrame;
 
-    RefPtr<WebCore::SharedBuffer> m_data;
+    RefPtr<WebCore::SharedBuffer::DataSegment> m_data;
     bool m_parseCompleted;
 };
index ff6a1c8..74337f1 100644 (file)
@@ -61,7 +61,7 @@ void ICOImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
 
     for (BMPReaders::iterator i(m_bmpReaders.begin()); i != m_bmpReaders.end(); ++i) {
         if (*i)
-            (*i)->setData(&data);
+            (*i)->setData(*m_data);
     }
     for (size_t i = 0; i < m_pngDecoders.size(); ++i)
         setDataForPNGDecoderAtIndex(i);
@@ -196,7 +196,7 @@ bool ICOImageDecoder::decodeAtIndex(size_t index)
             // we must not resize it again later (see caution in frameCount()).
             ASSERT(m_frameBufferCache.size() == m_dirEntries.size());
             m_bmpReaders[index] = makeUnique<BMPImageReader>(this, dirEntry.m_imageOffset, 0, true);
-            m_bmpReaders[index]->setData(m_data.get());
+            m_bmpReaders[index]->setData(*m_data);
             m_bmpReaders[index]->setBuffer(&m_frameBufferCache[index]);
         }
         m_frameSize = dirEntry.m_size;
index eb8d6e1..20cb7b6 100644 (file)
@@ -86,12 +86,12 @@ private:
 
     inline uint16_t readUint16(int offset) const
     {
-        return BMPImageReader::readUint16(m_data.get(), m_decodedOffset + offset);
+        return BMPImageReader::readUint16(*m_data, m_decodedOffset + offset);
     }
 
     inline uint32_t readUint32(int offset) const
     {
-        return BMPImageReader::readUint32(m_data.get(), m_decodedOffset + offset);
+        return BMPImageReader::readUint32(*m_data, m_decodedOffset + offset);
     }
 
     // If the desired PNGImageDecoder exists, gives it the appropriate data.
index 6f6cf0d..3ce1813 100644 (file)
@@ -266,7 +266,7 @@ public:
         m_bytesToSkip = std::max(numBytes - bytesToSkip, static_cast<long>(0));
     }
 
-    bool decode(const SharedBuffer& data, bool onlySize)
+    bool decode(const SharedBuffer::DataSegment& data, bool onlySize)
     {
         m_decodingSizeOnly = onlySize;
 
index 52631fb..b3c2784 100644 (file)
@@ -380,7 +380,7 @@ void JPEG2000ImageDecoder::decode(bool onlySize, bool allDataReceived)
     }
 
     struct Reader {
-        SharedBuffer& data;
+        SharedBuffer::DataSegment& data;
         size_t offset;
     } reader = { *m_data, 0 };
 
index 2a0ba15..8a1333c 100644 (file)
@@ -147,7 +147,7 @@ public:
         m_readOffset = 0;
     }
 
-    bool decode(const SharedBuffer& data, bool sizeOnly, unsigned haltAtFrame)
+    bool decode(const SharedBuffer::DataSegment& data, bool sizeOnly, unsigned haltAtFrame)
     {
         m_decodingSizeOnly = sizeOnly;
         PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png));
@@ -157,24 +157,16 @@ public:
             return decoder->setFailed();
 
         auto bytesToSkip = m_readOffset;
-        
-        // FIXME: Use getSomeData which is O(log(n)) instead of skipping bytes which is O(n).
-        for (const auto& element : data) {
-            if (bytesToSkip > element.segment->size()) {
-                bytesToSkip -= element.segment->size();
-                continue;
-            }
-            auto bytesToUse = element.segment->size() - bytesToSkip;
-            m_readOffset += bytesToUse;
-            m_currentBufferSize = m_readOffset;
-            png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(element.segment->data() + bytesToSkip)), bytesToUse);
-            bytesToSkip = 0;
-            // We explicitly specify the superclass encodedDataStatus() because we
-            // merely want to check if we've managed to set the size, not
-            // (recursively) trigger additional decoding if we haven't.
-            if (sizeOnly ? decoder->ScalableImageDecoder::encodedDataStatus() >= EncodedDataStatus::SizeAvailable : decoder->isCompleteAtIndex(haltAtFrame))
-                return true;
-        }
+        auto bytesToUse = data.size() - bytesToSkip;
+        m_readOffset += bytesToUse;
+        m_currentBufferSize = m_readOffset;
+        png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(data.data() + bytesToSkip)), bytesToUse);
+        // We explicitly specify the superclass encodedDataStatus() because we
+        // merely want to check if we've managed to set the size, not
+        // (recursively) trigger additional decoding if we haven't.
+        if (sizeOnly ? decoder->ScalableImageDecoder::encodedDataStatus() >= EncodedDataStatus::SizeAvailable : decoder->isCompleteAtIndex(haltAtFrame))
+            return true;
+
         return false;
     }
 
index 5698189..257040b 100644 (file)
@@ -132,7 +132,7 @@ void WEBPImageDecoder::decode(size_t frameIndex, bool allDataReceived)
     // This can be executed both in the main thread (when not using async decoding) or in the decoding thread.
     // When executed in the decoding thread, a call to setData() from the main thread may change the data
     // the WebPDemuxer is using, leaving it in an inconsistent state, so we need to protect the data.
-    RefPtr<SharedBuffer> protectedData(m_data);
+    RefPtr<SharedBuffer::DataSegment> protectedData(m_data);
     WebPData inputData = { reinterpret_cast<const uint8_t*>(protectedData->data()), protectedData->size() };
     WebPDemuxState demuxerState;
     WebPDemuxer* demuxer = WebPDemuxPartial(&inputData, &demuxerState);