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

Side by Side Diff: Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

Issue 1358643002: Fix caching bug in JPEGImageDecoder (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. 2 * Copyright (C) 2006 Apple Computer, Inc.
3 * 3 *
4 * Portions are Copyright (C) 2001-6 mozilla.org 4 * Portions are Copyright (C) 2001-6 mozilla.org
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Stuart Parmenter <stuart@mozilla.com> 7 * Stuart Parmenter <stuart@mozilla.com>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public 10 * modify it under the terms of the GNU Lesser General Public
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // We updated |next_input_byte|, so we need to update |m_lastByteSet| 385 // We updated |next_input_byte|, so we need to update |m_lastByteSet|
386 // so we know not to update |m_restartPosition| again. 386 // so we know not to update |m_restartPosition| again.
387 m_lastSetByte = m_info.src->next_input_byte; 387 m_lastSetByte = m_info.src->next_input_byte;
388 } 388 }
389 389
390 bool fillBuffer() 390 bool fillBuffer()
391 { 391 {
392 if (m_needsRestart) { 392 if (m_needsRestart) {
393 m_needsRestart = false; 393 m_needsRestart = false;
394 m_nextReadPosition = m_restartPosition; 394 m_nextReadPosition = m_restartPosition;
395 } else if (m_lastSetByte != m_info.src->next_input_byte) { 395 } else {
396 // next_input_byte was updated by jpeg, meaning that it found a rest art position. 396 updateRestartPosition();
397 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer ;
398 } 397 }
399 398
400 const char* segment; 399 const char* segment;
401 const unsigned bytes = m_data->getSomeData(segment, m_nextReadPosition); 400 const unsigned bytes = m_data->getSomeData(segment, m_nextReadPosition);
402 if (bytes == 0) { 401 if (bytes == 0) {
403 // We had to suspend. When we resume, we will need to start from the restart position. 402 suspend();
404 m_needsRestart = true;
405 // Let libjpeg know that the buffer needs to be refilled.
406 m_info.src->bytes_in_buffer = 0;
407 m_info.src->next_input_byte = nullptr;
408 m_lastSetByte = nullptr;
409 return false; 403 return false;
410 } 404 }
411 405
412 m_nextReadPosition += bytes; 406 m_nextReadPosition += bytes;
413 m_info.src->bytes_in_buffer = bytes; 407 m_info.src->bytes_in_buffer = bytes;
414 const JOCTET* nextByte = reinterpret_cast_ptr<const JOCTET*>(segment); 408 const JOCTET* nextByte = reinterpret_cast_ptr<const JOCTET*>(segment);
415 m_info.src->next_input_byte = nextByte; 409 m_info.src->next_input_byte = nextByte;
416 m_lastSetByte = nextByte; 410 m_lastSetByte = nextByte;
417 return true; 411 return true;
418 } 412 }
419 413
420 void setData(SharedBuffer* data) 414 void setData(SharedBuffer* data)
421 { 415 {
422 if (m_data.get() == data) 416 if (m_data.get() == data)
423 return; 417 return;
424 418
425 m_data = data; 419 m_data = data;
426 420
427 // If a restart is needed, the next call to fillBuffer will read from th e new SharedBuffer. 421 // If a restart is needed, the next call to fillBuffer will read from th e new SharedBuffer.
428 if (m_needsRestart) 422 if (m_needsRestart)
429 return; 423 return;
430 424
431 // Otherwise, empty the buffer, and leave the position the same, so fill Buffer continues 425 // Otherwise, empty the buffer, and leave the position the same, so fill Buffer continues
432 // reading from the same position in the new SharedBuffer. 426 // reading from the same position in the new SharedBuffer.
433 m_nextReadPosition -= m_info.src->bytes_in_buffer; 427 m_nextReadPosition -= m_info.src->bytes_in_buffer;
434 m_info.src->bytes_in_buffer = 0; 428 m_info.src->bytes_in_buffer = 0;
scroggo_chromium 2015/09/18 21:07:45 I considered calling suspend() here, which shares
Peter Kasting 2015/09/19 00:51:34 I like the idea of renaming this clearBuffer() and
scroggo_chromium 2015/09/21 18:21:27 Done.
435 m_info.src->next_input_byte = nullptr; 429 m_info.src->next_input_byte = nullptr;
436 m_lastSetByte = nullptr; 430 m_lastSetByte = nullptr;
437 } 431 }
438 432
439 bool decode(bool onlySize) 433 bool decode(bool onlySize)
440 { 434 {
441 // We need to do the setjmp here. Otherwise bad things will happen 435 // We need to do the setjmp here. Otherwise bad things will happen
442 if (setjmp(m_err.setjmp_buffer)) 436 if (setjmp(m_err.setjmp_buffer))
443 return m_decoder->setFailed(); 437 return m_decoder->setFailed();
444 438
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 518
525 // Don't allocate a giant and superfluous memory buffer when the 519 // Don't allocate a giant and superfluous memory buffer when the
526 // image is a sequential JPEG. 520 // image is a sequential JPEG.
527 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); 521 m_info.buffered_image = jpeg_has_multiple_scans(&m_info);
528 if (m_info.buffered_image) { 522 if (m_info.buffered_image) {
529 m_err.pub.emit_message = emit_message; 523 m_err.pub.emit_message = emit_message;
530 m_err.num_corrupt_warnings = 0; 524 m_err.num_corrupt_warnings = 0;
531 } 525 }
532 526
533 if (onlySize) { 527 if (onlySize) {
528 updateRestartPosition();
Peter Kasting 2015/09/19 00:51:34 You should probably have comments here about why y
scroggo_chromium 2015/09/21 18:21:28 Done. (My instinct is include lots of comments, b
529 suspend();
534 return true; 530 return true;
535 } 531 }
536 // FALL THROUGH 532 // FALL THROUGH
537 533
538 case JPEG_START_DECOMPRESS: 534 case JPEG_START_DECOMPRESS:
539 // Set parameters for decompression. 535 // Set parameters for decompression.
540 // FIXME -- Should reset dct_method and dither mode for final pass 536 // FIXME -- Should reset dct_method and dither mode for final pass
541 // of progressive JPEG. 537 // of progressive JPEG.
542 m_info.dct_method = JDCT_ISLOW; 538 m_info.dct_method = JDCT_ISLOW;
543 m_info.dither_mode = JDITHER_FS; 539 m_info.dither_mode = JDITHER_FS;
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 // We currently only support color profiles for RGB profiled images. 671 // We currently only support color profiles for RGB profiled images.
676 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); 672 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile));
677 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; 673 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8;
678 // FIXME: Don't force perceptual intent if the image profile contains an intent. 674 // FIXME: Don't force perceptual intent if the image profile contains an intent.
679 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL); 675 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL);
680 qcms_profile_release(inputProfile); 676 qcms_profile_release(inputProfile);
681 } 677 }
682 #endif 678 #endif
683 679
684 private: 680 private:
681 void updateRestartPosition()
682 {
683 if (m_lastSetByte != m_info.src->next_input_byte) {
684 // next_input_byte was updated by jpeg, meaning that it found a rest art position.
685 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer ;
686 }
687 }
688
689 void suspend()
690 {
691 // We had to suspend. When we resume, we will need to start from the res tart position.
692 m_needsRestart = true;
693 // Let libjpeg know that the buffer needs to be refilled.
694 m_info.src->bytes_in_buffer = 0;
695 m_info.src->next_input_byte = nullptr;
696 m_lastSetByte = nullptr;
697 }
698
685 RefPtr<SharedBuffer> m_data; 699 RefPtr<SharedBuffer> m_data;
686 JPEGImageDecoder* m_decoder; 700 JPEGImageDecoder* m_decoder;
687 // True if we need to back up to m_restartPosition. 701 // True if we need to back up to m_restartPosition.
688 bool m_needsRestart; 702 bool m_needsRestart;
689 // If libjpeg needed to restart, this is the position to restart from. 703 // If libjpeg needed to restart, this is the position to restart from.
690 unsigned m_restartPosition; 704 unsigned m_restartPosition;
691 // This is the position where we will read from, unless there is a restart. 705 // This is the position where we will read from, unless there is a restart.
692 unsigned m_nextReadPosition; 706 unsigned m_nextReadPosition;
693 // This is how we know to update the restart position. It is the last value 707 // This is how we know to update the restart position. It is the last value
694 // we set to next_input_byte. libjpeg will update next_input_byte when it 708 // we set to next_input_byte. libjpeg will update next_input_byte when it
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 // has failed. 1069 // has failed.
1056 if (!m_reader->decode(onlySize) && isAllDataReceived()) 1070 if (!m_reader->decode(onlySize) && isAllDataReceived())
1057 setFailed(); 1071 setFailed();
1058 1072
1059 // If decoding is done or failed, we don't need the JPEGImageReader anymore. 1073 // If decoding is done or failed, we don't need the JPEGImageReader anymore.
1060 if (isComplete(this, onlySize) || failed()) 1074 if (isComplete(this, onlySize) || failed())
1061 m_reader.clear(); 1075 m_reader.clear();
1062 } 1076 }
1063 1077
1064 } 1078 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698