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

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

Issue 1403393004: JPEGImageDecoder RGB565 and downsample support and related Skia imagegenerator changes Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Continued decoding fix and downscale combined Created 5 years, 1 month 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #error Blink assumes a little-endian target. 58 #error Blink assumes a little-endian target.
59 #endif 59 #endif
60 60
61 #if defined(JCS_ALPHA_EXTENSIONS) 61 #if defined(JCS_ALPHA_EXTENSIONS)
62 #define TURBO_JPEG_RGB_SWIZZLE 62 #define TURBO_JPEG_RGB_SWIZZLE
63 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). 63 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android).
64 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_RGBA; } 64 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_RGBA; }
65 #else // Output little-endian BGRA pixels. 65 #else // Output little-endian BGRA pixels.
66 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_BGRA; } 66 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_BGRA; }
67 #endif 67 #endif
68 inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == JCS_E XT_RGBA || colorSpace == JCS_EXT_BGRA; } 68 inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == JCS_E XT_RGBA || colorSpace == JCS_EXT_BGRA || colorSpace == JCS_RGB565; }
69 inline bool colorSpaceHasAlpha(J_COLOR_SPACE colorSpace) { return turboSwizzled( colorSpace); } 69 inline bool colorSpaceHasAlpha(J_COLOR_SPACE colorSpace) { return turboSwizzled( colorSpace); }
70 #else 70 #else
71 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_RGB; } 71 inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_RGB; }
72 inline bool colorSpaceHasAlpha(J_COLOR_SPACE) { return false; } 72 inline bool colorSpaceHasAlpha(J_COLOR_SPACE) { return false; }
73 #endif 73 #endif
74 74
75 namespace { 75 namespace {
76 76
77 const int exifMarker = JPEG_APP0 + 1; 77 const int exifMarker = JPEG_APP0 + 1;
78 78
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 return; 425 return;
426 426
427 // Otherwise, empty the buffer, and leave the position the same, so fill Buffer continues 427 // Otherwise, empty the buffer, and leave the position the same, so fill Buffer continues
428 // reading from the same position in the new SharedBuffer. 428 // reading from the same position in the new SharedBuffer.
429 m_nextReadPosition -= m_info.src->bytes_in_buffer; 429 m_nextReadPosition -= m_info.src->bytes_in_buffer;
430 clearBuffer(); 430 clearBuffer();
431 } 431 }
432 432
433 bool decode(bool onlySize) 433 bool decode(bool onlySize)
434 { 434 {
435 if ((m_state == JPEG_DECOMPRESS_SEQUENTIAL || m_state == JPEG_DECOMPRESS _PROGRESSIVE)
436 && m_decoder->hasFramebufferChanged()) {
437 // when previous attempts to decode failed with not all data availab le,
438 // decoder continues. Once that all data is available (and there is no alpha)
439 // and client calls decode to rgb565 or downsampling, it is needed t o restart decompression
440 // FIXME restart decompression without reading header
441 clearBuffer();
442 m_state = JPEG_HEADER;
443 }
444
435 // We need to do the setjmp here. Otherwise bad things will happen 445 // We need to do the setjmp here. Otherwise bad things will happen
436 if (setjmp(m_err.setjmp_buffer)) 446 if (setjmp(m_err.setjmp_buffer))
437 return m_decoder->setFailed(); 447 return m_decoder->setFailed();
438 448
439 J_COLOR_SPACE overrideColorSpace = JCS_UNKNOWN; 449 J_COLOR_SPACE overrideColorSpace = JCS_UNKNOWN;
440 switch (m_state) { 450 switch (m_state) {
441 case JPEG_HEADER: 451 case JPEG_HEADER:
442 // Read file parameters with jpeg_read_header(). 452 // Read file parameters with jpeg_read_header().
443 if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED) 453 if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED)
444 return false; // I/O suspension. 454 return false; // I/O suspension.
(...skipping 20 matching lines...) Expand all
465 break; 475 break;
466 case JCS_CMYK: 476 case JCS_CMYK:
467 case JCS_YCCK: 477 case JCS_YCCK:
468 // libjpeg can convert YCCK to CMYK, but neither to RGB, so we 478 // libjpeg can convert YCCK to CMYK, but neither to RGB, so we
469 // manually convert CMKY to RGB. 479 // manually convert CMKY to RGB.
470 m_info.out_color_space = JCS_CMYK; 480 m_info.out_color_space = JCS_CMYK;
471 break; 481 break;
472 default: 482 default:
473 return m_decoder->setFailed(); 483 return m_decoder->setFailed();
474 } 484 }
485 if (m_decoder->decodeToRGB565Enabled()) {
486 if (m_info.out_color_space == rgbOutputColorSpace()) {
487 // the rest would need to be converted manually on write
488 #if defined (JCS_ALPHA_EXTENSIONS)
489 m_info.out_color_space = JCS_RGB565;
490 #endif
491 #if USE(QCMSLIB)
492 // if there is colorprofile, use JCS_RGB as QCMS is not supp orting RGB565
493 // conversion, RGB->RGB565 happens in outputRows<>()
494 if (!m_decoder->ignoresGammaAndColorProfile())
495 m_info.out_color_space = JCS_RGB;
496 #endif
497 }
498 }
499 // FALL THROUGH
475 500
476 m_state = JPEG_START_DECOMPRESS; 501 m_state = JPEG_START_DECOMPRESS;
477 502
478 // We can fill in the size now that the header is available. 503 // We can fill in the size now that the header is available.
479 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) 504 if (!m_decoder->setSize(m_info.image_width, m_info.image_height))
480 return false; 505 return false;
481 506
482 // Calculate and set decoded size. 507 // Calculate and set decoded size.
483 m_info.scale_num = m_decoder->desiredScaleNumerator(); 508 m_info.scale_num = m_decoder->desiredScaleNumerator();
484 m_info.scale_denom = scaleDenominator; 509 m_info.scale_denom = scaleDenominator;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 return false; // I/O suspension. 606 return false; // I/O suspension.
582 607
583 // If we've completed image output... 608 // If we've completed image output...
584 ASSERT(m_info.output_scanline == m_info.output_height); 609 ASSERT(m_info.output_scanline == m_info.output_height);
585 m_state = JPEG_DONE; 610 m_state = JPEG_DONE;
586 } 611 }
587 // FALL THROUGH 612 // FALL THROUGH
588 613
589 case JPEG_DECOMPRESS_PROGRESSIVE: 614 case JPEG_DECOMPRESS_PROGRESSIVE:
590 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { 615 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) {
616
591 int status = 0; 617 int status = 0;
592 do { 618 do {
593 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_ mgr*>(m_info.err); 619 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_ mgr*>(m_info.err);
594 if (err->num_corrupt_warnings) 620 if (err->num_corrupt_warnings)
595 break; 621 break;
596 status = jpeg_consume_input(&m_info); 622 status = jpeg_consume_input(&m_info);
597 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E OI)); 623 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E OI));
598 624
599 for (;;) { 625 for (;;) {
600 if (!m_info.output_scanline) { 626 if (!m_info.output_scanline) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 799
774 void term_source(j_decompress_ptr jd) 800 void term_source(j_decompress_ptr jd)
775 { 801 {
776 decoder_source_mgr* src = reinterpret_cast_ptr<decoder_source_mgr*>(jd->src) ; 802 decoder_source_mgr* src = reinterpret_cast_ptr<decoder_source_mgr*>(jd->src) ;
777 src->decoder->decoder()->complete(); 803 src->decoder->decoder()->complete();
778 } 804 }
779 805
780 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfile Option colorOptions, size_t maxDecodedBytes) 806 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfile Option colorOptions, size_t maxDecodedBytes)
781 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) 807 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
782 , m_hasColorProfile(false) 808 , m_hasColorProfile(false)
809 , m_decodeColor(ImageFrame::RGBA8888)
810 , m_originalMaxDecodedBytes(maxDecodedBytes)
783 { 811 {
784 } 812 }
785 813
786 JPEGImageDecoder::~JPEGImageDecoder() 814 JPEGImageDecoder::~JPEGImageDecoder()
787 { 815 {
788 } 816 }
789 817
790 bool JPEGImageDecoder::setSize(unsigned width, unsigned height) 818 bool JPEGImageDecoder::setSize(unsigned width, unsigned height)
791 { 819 {
792 if (!ImageDecoder::setSize(width, height)) 820 if (!ImageDecoder::setSize(width, height))
(...skipping 21 matching lines...) Expand all
814 { 842 {
815 ASSERT((component >= 0) && (component <= 2) && m_reader); 843 ASSERT((component >= 0) && (component <= 2) && m_reader);
816 const jpeg_decompress_struct* info = m_reader->info(); 844 const jpeg_decompress_struct* info = m_reader->info();
817 845
818 ASSERT(info->out_color_space == JCS_YCbCr); 846 ASSERT(info->out_color_space == JCS_YCbCr);
819 return computeYUVSize(info, component, sizeType); 847 return computeYUVSize(info, component, sizeType);
820 } 848 }
821 849
822 unsigned JPEGImageDecoder::desiredScaleNumerator() const 850 unsigned JPEGImageDecoder::desiredScaleNumerator() const
823 { 851 {
824 size_t originalBytes = size().width() * size().height() * 4; 852 size_t originalBytes = size().width() * size().height()
853 * (decodeToRGB565Enabled() ? 2 : 4);
825 if (originalBytes <= m_maxDecodedBytes) { 854 if (originalBytes <= m_maxDecodedBytes) {
826 return scaleDenominator; 855 return scaleDenominator;
827 } 856 }
828 857
829 // Downsample according to the maximum decoded size. 858 // Downsample according to the maximum decoded size.
830 unsigned scaleNumerator = static_cast<unsigned>(floor(sqrt( 859 unsigned scaleNumerator = static_cast<unsigned>(floor(sqrt(
831 // MSVC needs explicit parameter type for sqrt(). 860 // MSVC needs explicit parameter type for sqrt().
832 static_cast<float>(m_maxDecodedBytes * scaleDenominator * scaleDenominat or / originalBytes)))); 861 static_cast<float>(m_maxDecodedBytes * scaleDenominator * scaleDenominat or / originalBytes))));
833 862
834 return scaleNumerator; 863 return scaleNumerator;
835 } 864 }
836 865
837 bool JPEGImageDecoder::canDecodeToYUV() 866 bool JPEGImageDecoder::canDecodeToYUV()
838 { 867 {
839 // Calling isSizeAvailable() ensures the reader is created and the output 868 // Calling isSizeAvailable() ensures the reader is created and the output
840 // color space is set. 869 // color space is set.
841 return isSizeAvailable() && m_reader->info()->out_color_space == JCS_YCbCr; 870 return isSizeAvailable() && m_reader->info()->out_color_space == JCS_YCbCr;
842 } 871 }
843 872
873 void JPEGImageDecoder::getAvailableDecodeAndScale(ImageFrame::ColorType* outType , float* scale, float* lowerScale)
874 {
875 if (outType) {
876 if (*outType != ImageFrame::RGBA8888 && *outType != ImageFrame::RGB565)
877 *outType = ImageFrame::RGBA8888;
878 }
879 if (scale) {
880 unsigned upper = static_cast<unsigned>(ceil(*scale * scaleDenominator));
881 upper = (upper > scaleDenominator) ? scaleDenominator : upper;
882 unsigned lower = upper - 1;
883 *scale = static_cast<float>(upper) / static_cast<float>(scaleDenominator );
884
885 if (lowerScale)
886 *lowerScale = static_cast<float>(lower) / static_cast<float>(scaleDe nominator);
887 return;
888 }
889 if (lowerScale)
890 *lowerScale = 1.0f;
891 }
892
893 bool JPEGImageDecoder::activateDecodeAndScale(ImageFrame::ColorType outColor, si ze_t maxDecodedBytes)
894 {
895 ASSERT(m_decodeColor == ImageFrame::RGBA8888);
896 if (outColor == ImageFrame::RGB565) {
897 m_decodeColor = ImageFrame::RGB565;
898 } else {
899 if (outColor != ImageFrame::RGBA8888) {
900 return false;
901 }
902 m_decodeColor = ImageFrame::RGBA8888;
903 }
904 m_originalMaxDecodedBytes = m_maxDecodedBytes;
905 m_maxDecodedBytes = maxDecodedBytes;
906 return true;
907 }
908
909 void JPEGImageDecoder::disableDecodeAndScale()
910 {
911 m_decodeColor = ImageFrame::RGBA8888;
912 m_maxDecodedBytes = m_originalMaxDecodedBytes;
913 }
914
915 bool JPEGImageDecoder::hasFramebufferChanged() const
916 {
917 // for decoding that doesn't restart (e.g. when previous decodings didn't ha ve
918 // all of the data, and meanwhile decoding to different output size was requ ested
919 if (m_frameBufferCache.isEmpty() || hasImagePlanes()) {
920 return false;
921 }
922 const ImageFrame& buffer = m_frameBufferCache[0];
923 // size is important here, not the decoded color - so use the current one
924 // when checking size change
925 if (buffer.status() != ImageFrame::FrameEmpty && !buffer.hasSize(m_decodedSi ze, m_decodeColor))
926 return true;
927 return false;
928 }
929
930
844 bool JPEGImageDecoder::decodeToYUV() 931 bool JPEGImageDecoder::decodeToYUV()
845 { 932 {
846 if (!hasImagePlanes()) 933 if (!hasImagePlanes())
847 return false; 934 return false;
848 PlatformInstrumentation::willDecodeImage("JPEG"); 935 PlatformInstrumentation::willDecodeImage("JPEG");
849 decode(false); 936 decode(false);
850 PlatformInstrumentation::didDecodeImage(); 937 PlatformInstrumentation::didDecodeImage();
851 return !failed(); 938 return !failed();
852 } 939 }
853 940
854 void JPEGImageDecoder::setImagePlanes(PassOwnPtr<ImagePlanes> imagePlanes) 941 void JPEGImageDecoder::setImagePlanes(PassOwnPtr<ImagePlanes> imagePlanes)
855 { 942 {
856 m_imagePlanes = imagePlanes; 943 m_imagePlanes = imagePlanes;
857 } 944 }
858 945
859 template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame ::PixelData* pixel, JSAMPARRAY samples, int column) 946 template <J_COLOR_SPACE colorSpace, class T> void setPixel(ImageFrame& buffer, T * pixel, JSAMPARRAY samples, int column)
860 { 947 {
861 ASSERT_NOT_REACHED(); 948 ASSERT_NOT_REACHED();
862 } 949 }
863 950
864 template <> void setPixel<JCS_RGB>(ImageFrame& buffer, ImageFrame::PixelData* pi xel, JSAMPARRAY samples, int column) 951 template <> void setPixel<JCS_RGB, ImageFrame::PixelData>(ImageFrame& buffer, Im ageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
865 { 952 {
866 JSAMPLE* jsample = *samples + column * 3; 953 JSAMPLE* jsample = *samples + column * 3;
867 buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255); 954 buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255);
868 } 955 }
869 956
870 template <> void setPixel<JCS_CMYK>(ImageFrame& buffer, ImageFrame::PixelData* p ixel, JSAMPARRAY samples, int column) 957 template <> void setPixel<JCS_CMYK, ImageFrame::PixelData>(ImageFrame& buffer, I mageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
871 { 958 {
872 JSAMPLE* jsample = *samples + column * 4; 959 JSAMPLE* jsample = *samples + column * 4;
873 960
874 // Source is 'Inverted CMYK', output is RGB. 961 // Source is 'Inverted CMYK', output is RGB.
875 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 962 // See: http://www.easyrgb.com/math.php?MATH=M12#text12
876 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb 963 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
877 // From CMYK to CMY: 964 // From CMYK to CMY:
878 // X = X * (1 - K ) + K [for X = C, M, or Y] 965 // X = X * (1 - K ) + K [for X = C, M, or Y]
879 // Thus, from Inverted CMYK to CMY is: 966 // Thus, from Inverted CMYK to CMY is:
880 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK 967 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
881 // From CMY (0..1) to RGB (0..1): 968 // From CMY (0..1) to RGB (0..1):
882 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] 969 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
883 unsigned k = jsample[3]; 970 unsigned k = jsample[3];
884 buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsample [2] * k / 255, 255); 971 buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsample [2] * k / 255, 255);
885 } 972 }
886 973
887 template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, Ima geFrame& buffer) 974 template <> void setPixel<JCS_RGB, ImageFrame::PixelData16>(ImageFrame& buffer, ImageFrame::PixelData16* pixel, JSAMPARRAY samples, int column)
975 {
976 JSAMPLE* jsample = *samples + column * 3;
977 buffer.setRGB565(pixel, jsample[0], jsample[1], jsample[2]);
978 }
979
980 template <> void setPixel<JCS_CMYK, ImageFrame::PixelData16>(ImageFrame& buffer, ImageFrame::PixelData16* pixel, JSAMPARRAY samples, int column)
981 {
982 JSAMPLE* jsample = *samples + column * 4;
983
984 // Source is 'Inverted CMYK', output is RGB.
985 // See: http://www.easyrgb.com/math.php?MATH=M12#text12
986 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
987 // From CMYK to CMY:
988 // X = X * (1 - K ) + K [for X = C, M, or Y]
989 // Thus, from Inverted CMYK to CMY is:
990 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
991 // From CMY (0..1) to RGB (0..1):
992 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
993 unsigned k = jsample[3];
994 buffer.setRGB565(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsample[ 2] * k / 255);
995 }
996
997 template <J_COLOR_SPACE colorSpace, class T> bool outputRows(JPEGImageReader* re ader, ImageFrame& buffer)
888 { 998 {
889 JSAMPARRAY samples = reader->samples(); 999 JSAMPARRAY samples = reader->samples();
890 jpeg_decompress_struct* info = reader->info(); 1000 jpeg_decompress_struct* info = reader->info();
891 int width = info->output_width; 1001 int width = info->output_width;
892 1002
893 while (info->output_scanline < info->output_height) { 1003 while (info->output_scanline < info->output_height) {
894 // jpeg_read_scanlines will increase the scanline counter, so we 1004 // jpeg_read_scanlines will increase the scanline counter, so we
895 // save the scanline before calling it. 1005 // save the scanline before calling it.
896 int y = info->output_scanline; 1006 int y = info->output_scanline;
897 // Request one scanline: returns 0 or 1 scanlines. 1007 // Request one scanline: returns 0 or 1 scanlines.
898 if (jpeg_read_scanlines(info, samples, 1) != 1) 1008 if (jpeg_read_scanlines(info, samples, 1) != 1)
899 return false; 1009 return false;
900 #if USE(QCMSLIB) 1010 #if USE(QCMSLIB)
901 if (reader->colorTransform() && colorSpace == JCS_RGB) 1011 if (reader->colorTransform() && colorSpace == JCS_RGB)
902 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi dth); 1012 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi dth);
903 #endif 1013 #endif
904 ImageFrame::PixelData* pixel = buffer.getAddr(0, y); 1014 T* pixel = buffer.getAddrT<T>(0, y);
905 for (int x = 0; x < width; ++pixel, ++x) 1015 for (int x = 0; x < width; ++pixel, ++x)
906 setPixel<colorSpace>(buffer, pixel, samples, x); 1016 setPixel<colorSpace, T>(buffer, pixel, samples, x);
907 } 1017 }
908 1018
909 buffer.setPixelsChanged(true); 1019 buffer.setPixelsChanged(true);
910 return true; 1020 return true;
911 } 1021 }
912 1022
913 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) 1023 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes)
914 { 1024 {
915 JSAMPARRAY samples = reader->samples(); 1025 JSAMPARRAY samples = reader->samples();
916 jpeg_decompress_struct* info = reader->info(); 1026 jpeg_decompress_struct* info = reader->info();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 return false; 1108 return false;
999 1109
1000 jpeg_decompress_struct* info = m_reader->info(); 1110 jpeg_decompress_struct* info = m_reader->info();
1001 1111
1002 // Initialize the framebuffer if needed. 1112 // Initialize the framebuffer if needed.
1003 ImageFrame& buffer = m_frameBufferCache[0]; 1113 ImageFrame& buffer = m_frameBufferCache[0];
1004 if (buffer.status() == ImageFrame::FrameEmpty) { 1114 if (buffer.status() == ImageFrame::FrameEmpty) {
1005 ASSERT(info->output_width == static_cast<JDIMENSION>(m_decodedSize.width ())); 1115 ASSERT(info->output_width == static_cast<JDIMENSION>(m_decodedSize.width ()));
1006 ASSERT(info->output_height == static_cast<JDIMENSION>(m_decodedSize.heig ht())); 1116 ASSERT(info->output_height == static_cast<JDIMENSION>(m_decodedSize.heig ht()));
1007 1117
1008 if (!buffer.setSize(info->output_width, info->output_height)) 1118 if (!buffer.setSize(info->output_width, info->output_height, decodeToRGB 565Enabled()
1119 ? ImageFrame::RGB565 : ImageFrame::RGBA8888))
1009 return setFailed(); 1120 return setFailed();
1010 buffer.setStatus(ImageFrame::FramePartial); 1121 buffer.setStatus(ImageFrame::FramePartial);
1011 // The buffer is transparent outside the decoded area while the image is 1122 // The buffer is transparent outside the decoded area while the image is
1012 // loading. The image will be marked fully opaque in complete(). 1123 // loading. The image will be marked fully opaque in complete().
1013 buffer.setHasAlpha(true); 1124 // For RGB565 this would just fail, having bitmap opaque during decoding
1125 // but, since RGB565 is used only for fully loaded content, this is not a problem
1126 if (!decodeToRGB565Enabled())
1127 buffer.setHasAlpha(true);
1014 1128
1015 // For JPEGs, the frame always fills the entire image. 1129 // For JPEGs, the frame always fills the entire image.
1016 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); 1130 buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
1017 } 1131 }
1018 1132
1019 #if defined(TURBO_JPEG_RGB_SWIZZLE) 1133 #if defined(TURBO_JPEG_RGB_SWIZZLE)
1020 if (turboSwizzled(info->out_color_space)) { 1134 if (turboSwizzled(info->out_color_space)) {
1021 while (info->output_scanline < info->output_height) { 1135 while (info->output_scanline < info->output_height) {
1022 unsigned char* row = reinterpret_cast_ptr<unsigned char*>(buffer.get Addr(0, info->output_scanline)); 1136 unsigned char* row = decodeToRGB565Enabled()
1023 if (jpeg_read_scanlines(info, &row, 1) != 1) 1137 ? reinterpret_cast_ptr<unsigned char*>(buffer.getAddrT<ImageFram e::PixelData16>(0, info->output_scanline))
1138 : reinterpret_cast_ptr<unsigned char*>(buffer.getAddr(0, info->o utput_scanline));
1139 if (jpeg_read_scanlines(info, &row, 1) != 1) {
1024 return false; 1140 return false;
1141 }
1025 #if USE(QCMSLIB) 1142 #if USE(QCMSLIB)
1026 if (qcms_transform* transform = m_reader->colorTransform()) 1143 if (qcms_transform* transform = m_reader->colorTransform())
1027 qcms_transform_data_type(transform, row, row, info->output_width , rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); 1144 qcms_transform_data_type(transform, row, row, info->output_width , rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX);
1028 #endif 1145 #endif
1029 } 1146 }
1030 buffer.setPixelsChanged(true); 1147 buffer.setPixelsChanged(true);
1031 return true; 1148 return true;
1032 } 1149 }
1033 #endif 1150 #endif
1034 1151
1035 switch (info->out_color_space) { 1152 switch (info->out_color_space) {
1036 case JCS_RGB: 1153 case JCS_RGB:
1037 return outputRows<JCS_RGB>(m_reader.get(), buffer); 1154 if (decodeToRGB565Enabled())
1155 return outputRows<JCS_RGB, ImageFrame::PixelData16>(m_reader.get(), buffer);
1156 return outputRows<JCS_RGB, ImageFrame::PixelData>(m_reader.get(), buffer );
1038 case JCS_CMYK: 1157 case JCS_CMYK:
1039 return outputRows<JCS_CMYK>(m_reader.get(), buffer); 1158 if (decodeToRGB565Enabled())
1159 return outputRows<JCS_CMYK, ImageFrame::PixelData16>(m_reader.get(), buffer);
1160 return outputRows<JCS_CMYK, ImageFrame::PixelData>(m_reader.get(), buffe r);
1040 default: 1161 default:
1041 ASSERT_NOT_REACHED(); 1162 ASSERT_NOT_REACHED();
1042 } 1163 }
1043 1164
1044 return setFailed(); 1165 return setFailed();
1045 } 1166 }
1046 1167
1047 void JPEGImageDecoder::complete() 1168 void JPEGImageDecoder::complete()
1048 { 1169 {
1049 if (m_frameBufferCache.isEmpty()) 1170 if (m_frameBufferCache.isEmpty())
(...skipping 26 matching lines...) Expand all
1076 // has failed. 1197 // has failed.
1077 if (!m_reader->decode(onlySize) && isAllDataReceived()) 1198 if (!m_reader->decode(onlySize) && isAllDataReceived())
1078 setFailed(); 1199 setFailed();
1079 1200
1080 // If decoding is done or failed, we don't need the JPEGImageReader anymore. 1201 // If decoding is done or failed, we don't need the JPEGImageReader anymore.
1081 if (isComplete(this, onlySize) || failed()) 1202 if (isComplete(this, onlySize) || failed())
1082 m_reader.clear(); 1203 m_reader.clear();
1083 } 1204 }
1084 1205
1085 } 1206 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698