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

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

Issue 15466004: Make image decoders faster by refactoring hot loops that fills the lines of ImageFrame. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Make image decoders faster by refactoring hot loops that fills the lines of ImageFrame. Created 7 years, 6 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 * Copyright (C) 2007-2009 Torch Mobile, Inc. 9 * Copyright (C) 2007-2009 Torch Mobile, Inc.
10 * 10 *
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 } 630 }
631 return &frame; 631 return &frame;
632 } 632 }
633 633
634 bool JPEGImageDecoder::setFailed() 634 bool JPEGImageDecoder::setFailed()
635 { 635 {
636 m_reader.clear(); 636 m_reader.clear();
637 return ImageDecoder::setFailed(); 637 return ImageDecoder::setFailed();
638 } 638 }
639 639
640 template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame ::PixelData* pixel, JSAMPARRAY samples, int column) 640 static bool outputRows(JPEGImageReader* reader, ImageFrame& buffer, J_COLOR_SPAC E colorSpace)
641 {
642 JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4);
643
644 switch (colorSpace) {
645 case JCS_RGB:
646 buffer.setRGBA(pixel, jsample[0], jsample[1], jsample[2], 0xFF);
647 break;
648 case JCS_CMYK:
649 // Source is 'Inverted CMYK', output is RGB.
650 // See: http://www.easyrgb.com/math.php?MATH=M12#text12
651 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
652 // From CMYK to CMY:
653 // X = X * (1 - K ) + K [for X = C, M, or Y]
654 // Thus, from Inverted CMYK to CMY is:
655 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
656 // From CMY (0..1) to RGB (0..1):
657 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
658 unsigned k = jsample[3];
659 buffer.setRGBA(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsampl e[2] * k / 255, 0xFF);
660 break;
661 }
662 }
663
664 template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, Ima geFrame& buffer)
665 { 641 {
666 JSAMPARRAY samples = reader->samples(); 642 JSAMPARRAY samples = reader->samples();
667 jpeg_decompress_struct* info = reader->info(); 643 jpeg_decompress_struct* info = reader->info();
668 int width = info->output_width; 644 int width = info->output_width;
669 645
670 while (info->output_scanline < info->output_height) { 646 while (info->output_scanline < info->output_height) {
671 // jpeg_read_scanlines will increase the scanline counter, so we 647 // jpeg_read_scanlines will increase the scanline counter, so we
672 // save the scanline before calling it. 648 // save the scanline before calling it.
673 int y = info->output_scanline; 649 int y = info->output_scanline;
674 // Request one scanline: returns 0 or 1 scanlines. 650 // Request one scanline: returns 0 or 1 scanlines.
675 if (jpeg_read_scanlines(info, samples, 1) != 1) 651 if (jpeg_read_scanlines(info, samples, 1) != 1)
676 return false; 652 return false;
677 #if USE(QCMSLIB) 653 #if USE(QCMSLIB)
678 if (reader->colorTransform() && colorSpace == JCS_RGB) 654 if (reader->colorTransform() && colorSpace == JCS_RGB)
679 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi dth); 655 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi dth);
680 #endif 656 #endif
681 ImageFrame::PixelData* pixel = buffer.getAddr(0, y); 657 unsigned const char* row = *samples;
682 for (int x = 0; x < width; ++pixel, ++x) 658 if (colorSpace == JCS_RGB)
683 setPixel<colorSpace>(buffer, pixel, samples, x); 659 buffer.fillRowFromRGBSource(y, row);
660 else if (colorSpace == JCS_CMYK)
661 buffer.fillRowFromInvertedCMYK(y, row);
662 else
663 ASSERT_NOT_REACHED();
684 } 664 }
685 665
686 return true; 666 return true;
687 } 667 }
688 668
689 bool JPEGImageDecoder::outputScanlines() 669 bool JPEGImageDecoder::outputScanlines()
690 { 670 {
691 if (m_frameBufferCache.isEmpty()) 671 if (m_frameBufferCache.isEmpty())
692 return false; 672 return false;
693 673
(...skipping 21 matching lines...) Expand all
715 return false; 695 return false;
716 #if USE(QCMSLIB) 696 #if USE(QCMSLIB)
717 if (qcms_transform* transform = m_reader->colorTransform()) 697 if (qcms_transform* transform = m_reader->colorTransform())
718 qcms_transform_data_type(transform, row, row, info->output_width , rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); 698 qcms_transform_data_type(transform, row, row, info->output_width , rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX);
719 #endif 699 #endif
720 } 700 }
721 return true; 701 return true;
722 } 702 }
723 #endif 703 #endif
724 704
725 switch (info->out_color_space) { 705 return outputRows(m_reader.get(), buffer, info->out_color_space);
726 case JCS_RGB:
727 return outputRows<JCS_RGB>(m_reader.get(), buffer);
728 case JCS_CMYK:
729 return outputRows<JCS_CMYK>(m_reader.get(), buffer);
730 default:
731 ASSERT_NOT_REACHED();
732 }
733
734 return setFailed();
735 } 706 }
736 707
737 void JPEGImageDecoder::jpegComplete() 708 void JPEGImageDecoder::jpegComplete()
738 { 709 {
739 if (m_frameBufferCache.isEmpty()) 710 if (m_frameBufferCache.isEmpty())
740 return; 711 return;
741 712
742 // Hand back an appropriately sized buffer, even if the image ended up being 713 // Hand back an appropriately sized buffer, even if the image ended up being
743 // empty. 714 // empty.
744 ImageFrame& buffer = m_frameBufferCache[0]; 715 ImageFrame& buffer = m_frameBufferCache[0];
(...skipping 13 matching lines...) Expand all
758 // has failed. 729 // has failed.
759 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) 730 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived())
760 setFailed(); 731 setFailed();
761 // If we're done decoding the image, we don't need the JPEGImageReader 732 // If we're done decoding the image, we don't need the JPEGImageReader
762 // anymore. (If we failed, |m_reader| has already been cleared.) 733 // anymore. (If we failed, |m_reader| has already been cleared.)
763 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() == ImageFrame::FrameComplete)) 734 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() == ImageFrame::FrameComplete))
764 m_reader.clear(); 735 m_reader.clear();
765 } 736 }
766 737
767 } 738 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698