Changeset 136189 in webkit
- Timestamp:
- Nov 29, 2012, 5:15:15 PM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
platform/image-decoders/jpeg/JPEGImageDecoder.cpp (modified) (2 diffs)
-
platform/image-decoders/jpeg/JPEGImageDecoder.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r136188 r136189 1 2012-11-29 Viatcheslav Ostapenko <v.ostapenko@samsung.com> 2 3 Optimization in image decoding. 4 https://bugs.webkit.org/show_bug.cgi?id=88424 5 6 Reviewed by Brent Fulgham. 7 8 Reduce branching and multiplications in JPEG image decoding loops and functions. 9 Code is moved to the template functions with scale and color space template parameters 10 because they were reason of branches inside loops. With templated funtions compiler 11 will generate separate instance of function for every set of parameters removing 12 unreachable code in every condition where constant value is used. 13 14 Rebase and update of original patch by Misha Tyutyunik <michael.tyuytunik@nokia.com> . 15 16 Thanks to Noel Gordon for his help in cleaning up remaining issues. 17 18 Covered by existing tests. 19 20 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: 21 (WebCore): 22 (WebCore::setPixel): 23 (WebCore::JPEGImageDecoder::outputScanlines): 24 * platform/image-decoders/jpeg/JPEGImageDecoder.h: 25 (JPEGImageDecoder): 26 1 27 2012-11-29 Kentaro Hara <haraken@chromium.org> 2 28 -
trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r132961 r136189 647 647 } 648 648 649 template <int colorSpace> 650 void setPixel(ImageFrame& buffer, ImageFrame::PixelData* currentAddress, JSAMPARRAY samples, int column) 651 { 652 JSAMPLE* jsample = *samples + column * (static_cast<J_COLOR_SPACE>(colorSpace) == JCS_RGB ? 3 : 4); 653 654 switch (static_cast<J_COLOR_SPACE>(colorSpace)) { 655 #if defined(TURBO_JPEG_RGB_SWIZZLE) 656 case JCS_EXT_BGRA: 657 buffer.setRGBA(currentAddress, jsample[2], jsample[1], jsample[1], 0xFF); 658 break; 659 case JCS_EXT_RGBA: // Fallback to JSC_RGB case here. 660 #endif 661 case JCS_RGB: 662 buffer.setRGBA(currentAddress, jsample[0], jsample[1], jsample[2], 0xFF); 663 break; 664 case JCS_CMYK: 665 // Source is 'Inverted CMYK', output is RGB. 666 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 667 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb 668 // From CMYK to CMY: 669 // X = X * (1 - K ) + K [for X = C, M, or Y] 670 // Thus, from Inverted CMYK to CMY is: 671 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK 672 // From CMY (0..1) to RGB (0..1): 673 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] 674 unsigned k = jsample[3]; 675 buffer.setRGBA(currentAddress, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF); 676 break; 677 } 678 } 679 680 template <int colorSpace, bool isScaled> 681 bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) 682 { 683 JSAMPARRAY samples = m_reader->samples(); 684 jpeg_decompress_struct* info = m_reader->info(); 685 686 int width = isScaled ? m_scaledColumns.size() : info->output_width; 687 688 while (info->output_scanline < info->output_height) { 689 // jpeg_read_scanlines will increase the scanline counter, so we 690 // save the scanline before calling it. 691 int sourceY = info->output_scanline; 692 /* Request one scanline. Returns 0 or 1 scanlines. */ 693 if (jpeg_read_scanlines(info, samples, 1) != 1) 694 return false; 695 696 int destY = scaledY(sourceY); 697 if (destY < 0) 698 continue; 699 700 #if USE(QCMSLIB) 701 if (m_reader->colorTransform() && colorSpace == JCS_RGB) 702 qcms_transform_data(m_reader->colorTransform(), *samples, *samples, info->output_width); 703 #endif 704 705 ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY); 706 707 for (int x = 0; x < width; ++x) { 708 setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x); 709 ++currentAddress; 710 } 711 } 712 return true; 713 } 714 715 template <int colorSpace> 716 bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) 717 { 718 return m_scaled ? outputScanlines<colorSpace, true>(buffer) : outputScanlines<colorSpace, false>(buffer); 719 } 720 649 721 bool JPEGImageDecoder::outputScanlines() 650 722 { … … 685 757 #endif 686 758 687 JSAMPARRAY samples = m_reader->samples(); 688 689 while (info->output_scanline < info->output_height) { 690 // jpeg_read_scanlines will increase the scanline counter, so we 691 // save the scanline before calling it. 692 int sourceY = info->output_scanline; 693 /* Request one scanline. Returns 0 or 1 scanlines. */ 694 if (jpeg_read_scanlines(info, samples, 1) != 1) 695 return false; 696 697 int destY = scaledY(sourceY); 698 if (destY < 0) 699 continue; 700 #if USE(QCMSLIB) 701 if (m_reader->colorTransform() && info->out_color_space == JCS_RGB) 702 qcms_transform_data(m_reader->colorTransform(), *samples, *samples, info->output_width); 703 #endif 704 int width = m_scaled ? m_scaledColumns.size() : info->output_width; 705 for (int x = 0; x < width; ++x) { 706 JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4); 707 if (info->out_color_space == JCS_RGB) 708 buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); 759 switch (info->out_color_space) { 760 // The code inside outputScanlines<int, bool> will be executed 761 // for each pixel, so we want to avoid any extra comparisons there. 762 // That is why we use template and template specializations here so 763 // the proper code will be generated at compile time. 764 case JCS_RGB: 765 return outputScanlines<JCS_RGB>(buffer); 709 766 #if defined(TURBO_JPEG_RGB_SWIZZLE) 710 else if (info->out_color_space == JCS_EXT_RGBA) 711 buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); 712 else if (info->out_color_space == JCS_EXT_BGRA) 713 buffer.setRGBA(x, destY, jsample[2], jsample[1], jsample[0], 0xFF); 714 #endif 715 else if (info->out_color_space == JCS_CMYK) { 716 // Source is 'Inverted CMYK', output is RGB. 717 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 718 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb 719 // From CMYK to CMY: 720 // X = X * (1 - K ) + K [for X = C, M, or Y] 721 // Thus, from Inverted CMYK to CMY is: 722 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK 723 // From CMY (0..1) to RGB (0..1): 724 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] 725 unsigned k = jsample[3]; 726 buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF); 727 } else { 728 ASSERT_NOT_REACHED(); 729 return setFailed(); 730 } 731 } 732 } 733 734 return true; 767 case JCS_EXT_RGBA: 768 return outputScanlines<JCS_EXT_RGBA>(buffer); 769 case JCS_EXT_BGRA: 770 return outputScanlines<JCS_EXT_BGRA>(buffer); 771 #endif 772 case JCS_CMYK: 773 return outputScanlines<JCS_CMYK>(buffer); 774 default: 775 ASSERT_NOT_REACHED(); 776 } 777 778 return setFailed(); 735 779 } 736 780 -
trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r132260 r136189 63 63 void decode(bool onlySize); 64 64 65 template <int colorSpace> 66 bool outputScanlines(ImageFrame& buffer); 67 68 template <int colorSpace, bool isScaled> 69 bool outputScanlines(ImageFrame& buffer); 70 65 71 OwnPtr<JPEGImageReader> m_reader; 66 72 };
Note:
See TracChangeset
for help on using the changeset viewer.