Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/image-decoders/SegmentReader.h" | |
| 6 | |
| 7 #include "third_party/skia/src/core/SkRWBuffer.h" | |
| 8 #include "wtf/Assertions.h" | |
| 9 #include "wtf/Noncopyable.h" | |
| 10 #include "wtf/PassRefPtr.h" | |
| 11 #include "wtf/RefPtr.h" | |
| 12 | |
| 13 namespace blink { | |
| 14 | |
| 15 class ROBufferSegmentReader final : public SegmentReader { | |
| 16 WTF_MAKE_NONCOPYABLE(ROBufferSegmentReader); | |
| 17 public: | |
| 18 ROBufferSegmentReader(PassRefPtr<SkROBuffer>); | |
| 19 | |
| 20 size_t getSomeData(const char*& data, size_t position) const override; | |
| 21 size_t size() const override { return m_roBuffer ? m_roBuffer->size() : 0; } | |
|
Peter Kasting
2016/03/25 06:24:37
Nit: Why define this inline (and nothing else)?
scroggo
2016/03/25 15:49:53
Because it's short. What is your preference?
Peter Kasting
2016/03/25 21:15:56
I generally avoid inlining virtuals (see "stop inl
scroggo_chromium
2016/03/25 21:31:59
Good enough reason to me not to inline, for consis
| |
| 22 PassRefPtr<SkData> getAsSkData() const override; | |
| 23 | |
| 24 private: | |
| 25 RefPtr<SkROBuffer> m_roBuffer; | |
| 26 // Position of the first char in the current block of m_iter. | |
| 27 mutable size_t m_positionOfBlock; | |
| 28 mutable SkROBuffer::Iter m_iter; | |
| 29 }; | |
| 30 | |
| 31 PassRefPtr<SegmentReader> SegmentReader::createFromSkROBuffer(PassRefPtr<SkROBuf fer> buffer) | |
| 32 { | |
| 33 return adoptRef(new ROBufferSegmentReader(buffer)); | |
| 34 } | |
| 35 | |
| 36 ROBufferSegmentReader::ROBufferSegmentReader(PassRefPtr<SkROBuffer> buffer) | |
| 37 : m_roBuffer(buffer) | |
| 38 , m_positionOfBlock(0) | |
| 39 , m_iter(m_roBuffer.get()) | |
| 40 {} | |
| 41 | |
| 42 size_t ROBufferSegmentReader::getSomeData(const char*& data, size_t position) co nst | |
| 43 { | |
| 44 if (!m_roBuffer) | |
| 45 return 0; | |
| 46 | |
| 47 if (position < m_positionOfBlock) { | |
| 48 // SkROBuffer::Iter only iterates forwards. Start from the | |
| 49 // beginning. | |
| 50 m_iter.reset(m_roBuffer.get()); | |
| 51 m_positionOfBlock = 0; | |
| 52 } | |
| 53 | |
| 54 while (true) { | |
|
Peter Kasting
2016/03/25 06:24:37
Nit: Could write this as
for (size_t sizeOfBl
scroggo
2016/03/25 15:49:53
Done.
| |
| 55 ASSERT(m_positionOfBlock <= position); | |
| 56 | |
| 57 const size_t sizeOfBlock = m_iter.size(); | |
| 58 if (sizeOfBlock == 0) { | |
| 59 return 0; | |
| 60 } | |
| 61 | |
| 62 if (m_positionOfBlock + sizeOfBlock > position) { | |
| 63 // |position| is in this block. | |
| 64 const size_t positionInBlock = position - m_positionOfBlock; | |
| 65 data = static_cast<const char*>(m_iter.data()) + positionInBlock; | |
| 66 return sizeOfBlock - positionInBlock; | |
| 67 } | |
| 68 | |
| 69 // Move to next block. | |
| 70 if (!m_iter.next()) { | |
| 71 // Reset to the beginning, so future calls can succeed. | |
| 72 m_iter.reset(m_roBuffer.get()); | |
| 73 m_positionOfBlock = 0; | |
| 74 return 0; | |
| 75 } | |
| 76 | |
| 77 m_positionOfBlock += sizeOfBlock; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 static void unrefRobuffer(const void* ptr, void* context) | |
|
Peter Kasting
2016/03/25 06:24:37
Nit: ROBuffer?
scroggo
2016/03/25 15:49:53
Done.
| |
| 82 { | |
| 83 static_cast<SkROBuffer*>(context)->unref(); | |
| 84 } | |
| 85 | |
| 86 PassRefPtr<SkData> ROBufferSegmentReader::getAsSkData() const | |
| 87 { | |
| 88 if (!m_roBuffer) | |
| 89 return nullptr; | |
| 90 | |
| 91 // Check to see if the data is already contiguous. | |
| 92 SkROBuffer::Iter iter(m_roBuffer.get()); | |
| 93 const bool multipleBlocks = iter.next(); | |
| 94 iter.reset(m_roBuffer.get()); | |
| 95 | |
| 96 if (multipleBlocks) { | |
| 97 SkData* data = SkData::NewUninitialized(m_roBuffer->size()); | |
| 98 char* dst = static_cast<char*>(data->writable_data()); | |
| 99 do { | |
| 100 size_t size = iter.size(); | |
| 101 memcpy(dst, iter.data(), size); | |
| 102 dst += size; | |
| 103 } while (iter.next()); | |
| 104 return adoptRef(data); | |
| 105 } | |
| 106 | |
| 107 // Contiguous data. No need to copy. | |
|
Peter Kasting
2016/03/25 06:24:37
Nit: It's a little weird to see:
// Check to
scroggo
2016/03/25 15:49:53
Done.
| |
| 108 m_roBuffer->ref(); | |
| 109 return adoptRef(SkData::NewWithProc(iter.data(), iter.size(), &unrefRobuffer , m_roBuffer.get())); | |
| 110 } | |
| 111 | |
| 112 } // namespace blink | |
| OLD | NEW |