Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Side by Side Diff: src/codec/SkRawCodec.cpp

Issue 1645963002: Optimize the SkRawStream when the input is an asset stream (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodec.h" 8 #include "SkCodec.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 } 157 }
158 }; 158 };
159 159
160 } // namespace 160 } // namespace
161 161
162 // Note: this class could throw exception if it is used as dng_stream. 162 // Note: this class could throw exception if it is used as dng_stream.
163 class SkRawStream : public ::piex::StreamInterface { 163 class SkRawStream : public ::piex::StreamInterface {
164 public: 164 public:
165 // Note that this call will take the ownership of stream. 165 // Note that this call will take the ownership of stream.
166 explicit SkRawStream(SkStream* stream) 166 explicit SkRawStream(SkStream* stream)
167 : fStream(stream), fWholeStreamRead(false) {} 167 : fStream(stream)
168 , fWholeStreamRead(false)
169 , fIsMemoryStream(fStream->getMemoryBase() != nullptr) {}
adaubert 2016/01/28 11:54:22 Would it be better to use a dynamic_cast? E.g. fI
yujieqin 2016/01/28 12:25:14 error: ‘dynamic_cast’ not permitted with -fno-rtti
168 170
169 ~SkRawStream() override {} 171 ~SkRawStream() override {}
170 172
171 /* 173 /*
172 * Creates an SkMemoryStream from the offset with size. 174 * Creates an SkMemoryStream from the offset with size.
173 * Note: for performance reason, this function is destructive to the SkRawSt ream. One should 175 * Note: for performance reason, this function is destructive to the SkRawSt ream. One should
174 * abandon current object after the function call. 176 * abandon current object after the function call.
175 */ 177 */
176 SkMemoryStream* transferBuffer(size_t offset, size_t size) { 178 SkMemoryStream* transferBuffer(size_t offset, size_t size) {
179 if (fIsMemoryStream) {
180 size_t sum;
181 if (!safe_add_to_size_t(offset, size, &sum) ||
182 (sum > fStream->getLength()) ||
msarett 2016/01/28 17:25:40 I don't think we necessarily want to fail if (sum
yujieqin 2016/02/01 12:59:47 Done
183 !fStream->seek(offset)) {
184 return nullptr;
185 }
186 return static_cast<SkMemoryStream*>(fStream.release());
adaubert 2016/01/28 11:54:22 dynamic_cast?
yujieqin 2016/01/28 12:25:14 error: ‘dynamic_cast’ not permitted with -fno-rtti
scroggo 2016/01/28 18:53:44 This isn't safe. Another implementation can implem
yujieqin 2016/02/01 12:59:47 I tried to change to use the peekData() based on y
187 }
188
177 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size)); 189 SkAutoTUnref<SkData> data(SkData::NewUninitialized(size));
178 if (offset > fStreamBuffer.bytesWritten()) { 190 if (offset > fStreamBuffer.bytesWritten()) {
179 // If the offset is not buffered, read from fStream directly and ski p the buffering. 191 // If the offset is not buffered, read from fStream directly and ski p the buffering.
180 const size_t skipLength = offset - fStreamBuffer.bytesWritten(); 192 const size_t skipLength = offset - fStreamBuffer.bytesWritten();
181 if (fStream->skip(skipLength) != skipLength) { 193 if (fStream->skip(skipLength) != skipLength) {
182 return nullptr; 194 return nullptr;
183 } 195 }
184 const size_t bytesRead = fStream->read(data->writable_data(), size); 196 const size_t bytesRead = fStream->read(data->writable_data(), size);
185 if (bytesRead < size) { 197 if (bytesRead < size) {
186 data.reset(SkData::NewSubset(data.get(), 0, bytesRead)); 198 data.reset(SkData::NewSubset(data.get(), 0, bytesRead));
187 } 199 }
188 } else { 200 } else {
189 const size_t alreadyBuffered = SkTMin(fStreamBuffer.bytesWritten() - offset, size); 201 const size_t alreadyBuffered = SkTMin(fStreamBuffer.bytesWritten() - offset, size);
190 if (alreadyBuffered > 0 && 202 if (alreadyBuffered > 0 &&
191 !fStreamBuffer.read(data->writable_data(), offset, alreadyBuffer ed)) { 203 !fStreamBuffer.read(data->writable_data(), offset, alreadyBuffer ed)) {
192 return nullptr; 204 return nullptr;
193 } 205 }
194 206
195 const size_t remaining = size - alreadyBuffered; 207 const size_t remaining = size - alreadyBuffered;
196 if (remaining) { 208 if (remaining) {
197 auto* dst = static_cast<uint8_t*>(data->writable_data()) + alrea dyBuffered; 209 auto* dst = static_cast<uint8_t*>(data->writable_data()) + alrea dyBuffered;
198 const size_t bytesRead = fStream->read(dst, remaining); 210 const size_t bytesRead = fStream->read(dst, remaining);
199 size_t newSize; 211 size_t newSize;
200 if (bytesRead < remaining) { 212 if (bytesRead < remaining) {
201 if (!safe_add_to_size_t(alreadyBuffered, bytesRead, &newSize )) { 213 if (!safe_add_to_size_t(alreadyBuffered, bytesRead, &newSize )) {
msarett 2016/01/28 17:25:40 I realize that this is unrelated to this change, b
msarett 2016/02/01 16:23:43 PTAL
202 return nullptr; 214 return nullptr;
203 } 215 }
204 data.reset(SkData::NewSubset(data.get(), 0, newSize)); 216 data.reset(SkData::NewSubset(data.get(), 0, newSize));
205 } 217 }
206 } 218 }
207 } 219 }
208 return new SkMemoryStream(data); 220 return new SkMemoryStream(data);
209 } 221 }
210 222
211 // For PIEX 223 // For PIEX
212 ::piex::Error GetData(const size_t offset, const size_t length, 224 ::piex::Error GetData(const size_t offset, const size_t length,
213 uint8* data) override { 225 uint8* data) override {
214 if (offset == 0 && length == 0) { 226 return read(offset, length, static_cast<void*>(data)) ?
215 return ::piex::Error::kOk; 227 ::piex::Error::kOk : ::piex::Error::kFail;
216 }
217 size_t sum;
218 if (!safe_add_to_size_t(offset, length, &sum) || !this->bufferMoreData(s um)) {
219 return ::piex::Error::kFail;
220 }
221 if (!fStreamBuffer.read(data, offset, length)) {
222 return ::piex::Error::kFail;
223 }
224 return ::piex::Error::kOk;
225 } 228 }
226 229
227 // For dng_stream 230 // For dng_stream
228 uint64 getLength() { 231 uint64 getLength() {
229 if (!this->bufferMoreData(kReadToEnd)) { // read whole stream 232 if (fIsMemoryStream) {
230 ThrowReadFile(); 233 return fStream->getLength();
234 } else {
235 if (!this->bufferMoreData(kReadToEnd)) { // read whole stream
236 ThrowReadFile();
237 }
238 return fStreamBuffer.bytesWritten();
231 } 239 }
232 return fStreamBuffer.bytesWritten();
233 } 240 }
234 241
235 // For dng_stream 242 // For dng_stream
236 void read(void* data, uint32 count, uint64 offset) { 243 void read(void* data, uint32 count, uint64 offset) {
237 if (count == 0 && offset == 0) {
238 return;
239 }
240 size_t sum; 244 size_t sum;
241 if (!safe_add_to_size_t(static_cast<uint64>(count), offset, &sum) || 245 if (!safe_add_to_size_t(static_cast<uint64>(count), offset, &sum) ||
msarett 2016/01/28 17:25:40 Is this check unnecessary? It looks like we will
yujieqin 2016/02/01 12:59:47 Actually I think it is necessary. Because the spec
msarett 2016/02/01 16:23:43 Acknowledged.
242 !this->bufferMoreData(sum)) { 246 !read(static_cast<size_t>(offset), static_cast<size_t>(count), data) ) {
243 ThrowReadFile();
244 }
245
246 if (!fStreamBuffer.read(data, static_cast<size_t>(offset), count)) {
247 ThrowReadFile(); 247 ThrowReadFile();
248 } 248 }
249 } 249 }
250 250
251 private: 251 private:
252 bool read(size_t offset, size_t length, void* data) {
msarett 2016/01/28 17:25:40 I find it confusing to have two functions both nam
yujieqin 2016/02/01 12:59:47 changed the other read to dngRead().
253 if (offset == 0 && length == 0) {
254 return true;
255 }
256
257 size_t sum;
258 if (!safe_add_to_size_t(offset, length, &sum)) {
259 return false;
260 }
261
262 if (fIsMemoryStream) {
263 if (sum > fStream->getLength()) {
264 return false;
265 }
266
267 return fStream->seek(offset) &&
268 (fStream->read(data, length) == length);
269 } else {
270 return this->bufferMoreData(sum) && fStreamBuffer.read(data, offset, length);
271 }
272 }
273
252 // Note: if the newSize == kReadToEnd (0), this function will read to the en d of stream. 274 // Note: if the newSize == kReadToEnd (0), this function will read to the en d of stream.
253 bool bufferMoreData(size_t newSize) { 275 bool bufferMoreData(size_t newSize) {
276 SkASSERT(!fIsMemoryStream);
277
254 if (newSize == kReadToEnd) { 278 if (newSize == kReadToEnd) {
255 if (fWholeStreamRead) { // already read-to-end. 279 if (fWholeStreamRead) { // already read-to-end.
256 return true; 280 return true;
257 } 281 }
258 282
259 // TODO: optimize for the special case when the input is SkMemoryStr eam. 283 // TODO: optimize for the special case when the input is SkMemoryStr eam.
260 return SkStreamCopy(&fStreamBuffer, fStream.get()); 284 return SkStreamCopy(&fStreamBuffer, fStream.get());
261 } 285 }
262 286
263 if (newSize <= fStreamBuffer.bytesWritten()) { // already buffered to n ewSize 287 if (newSize <= fStreamBuffer.bytesWritten()) { // already buffered to n ewSize
264 return true; 288 return true;
265 } 289 }
266 if (fWholeStreamRead) { // newSize is larger than the whole stream. 290 if (fWholeStreamRead) { // newSize is larger than the whole stream.
267 return false; 291 return false;
268 } 292 }
269 293
270 const size_t sizeToRead = newSize - fStreamBuffer.bytesWritten(); 294 const size_t sizeToRead = newSize - fStreamBuffer.bytesWritten();
271 SkAutoTMalloc<uint8> tempBuffer(sizeToRead); 295 SkAutoTMalloc<uint8> tempBuffer(sizeToRead);
272 const size_t bytesRead = fStream->read(tempBuffer.get(), sizeToRead); 296 const size_t bytesRead = fStream->read(tempBuffer.get(), sizeToRead);
273 if (bytesRead != sizeToRead) { 297 if (bytesRead != sizeToRead) {
274 return false; 298 return false;
275 } 299 }
276 return fStreamBuffer.write(tempBuffer.get(), bytesRead); 300 return fStreamBuffer.write(tempBuffer.get(), bytesRead);
277 } 301 }
278 302
279 SkAutoTDelete<SkStream> fStream; 303 SkAutoTDelete<SkStream> fStream;
280 bool fWholeStreamRead; 304 bool fWholeStreamRead;
305 bool fIsMemoryStream;
281 306
282 SkDynamicMemoryWStream fStreamBuffer; 307 SkDynamicMemoryWStream fStreamBuffer;
283 308
284 const size_t kReadToEnd = 0; 309 const size_t kReadToEnd = 0;
285 }; 310 };
286 311
287 class SkDngStream : public dng_stream { 312 class SkDngStream : public dng_stream {
288 public: 313 public:
289 SkDngStream(SkRawStream* rawStream) : fRawStream(rawStream) {} 314 SkDngStream(SkRawStream* rawStream) : fRawStream(rawStream) {}
290 315
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 SkISize sizeFloor = this->onGetScaledDimensions(1.f / std::floor(fullShortEd ge / shortEdge)); 584 SkISize sizeFloor = this->onGetScaledDimensions(1.f / std::floor(fullShortEd ge / shortEdge));
560 SkISize sizeCeil = this->onGetScaledDimensions(1.f / std::ceil(fullShortEdge / shortEdge)); 585 SkISize sizeCeil = this->onGetScaledDimensions(1.f / std::ceil(fullShortEdge / shortEdge));
561 return sizeFloor == dim || sizeCeil == dim; 586 return sizeFloor == dim || sizeCeil == dim;
562 } 587 }
563 588
564 SkRawCodec::~SkRawCodec() {} 589 SkRawCodec::~SkRawCodec() {}
565 590
566 SkRawCodec::SkRawCodec(SkDngImage* dngImage) 591 SkRawCodec::SkRawCodec(SkDngImage* dngImage)
567 : INHERITED(dngImage->getImageInfo(), nullptr) 592 : INHERITED(dngImage->getImageInfo(), nullptr)
568 , fDngImage(dngImage) {} 593 , fDngImage(dngImage) {}
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698