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

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

Issue 2436223002: Revert of Use SkColorSpaceXform to handle color conversions in decoders (Closed)
Patch Set: Created 4 years, 2 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "wtf/PtrUtil.h" 42 #include "wtf/PtrUtil.h"
43 #include "wtf/Threading.h" 43 #include "wtf/Threading.h"
44 #include <memory> 44 #include <memory>
45 45
46 extern "C" { 46 extern "C" {
47 #include <stdio.h> // jpeglib.h needs stdio FILE. 47 #include <stdio.h> // jpeglib.h needs stdio FILE.
48 #include "jpeglib.h" 48 #include "jpeglib.h"
49 #if USE(ICCJPEG) 49 #if USE(ICCJPEG)
50 #include "iccjpeg.h" 50 #include "iccjpeg.h"
51 #endif 51 #endif
52 #if USE(QCMSLIB)
53 #include "qcms.h"
54 #endif
52 #include <setjmp.h> 55 #include <setjmp.h>
53 } 56 }
54 57
55 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) 58 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN)
56 #error Blink assumes a little-endian target. 59 #error Blink assumes a little-endian target.
57 #endif 60 #endif
58 61
59 #if defined(JCS_ALPHA_EXTENSIONS) 62 #if defined(JCS_ALPHA_EXTENSIONS)
60 #define TURBO_JPEG_RGB_SWIZZLE 63 #define TURBO_JPEG_RGB_SWIZZLE
61 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). 64 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android).
62 inline J_COLOR_SPACE rgbOutputColorSpace() { 65 inline J_COLOR_SPACE rgbOutputColorSpace() {
63 return JCS_EXT_RGBA; 66 return JCS_EXT_RGBA;
64 } 67 }
65 #else // Output little-endian BGRA pixels. 68 #else // Output little-endian BGRA pixels.
66 inline J_COLOR_SPACE rgbOutputColorSpace() { 69 inline J_COLOR_SPACE rgbOutputColorSpace() {
67 return JCS_EXT_BGRA; 70 return JCS_EXT_BGRA;
68 } 71 }
69 #endif 72 #endif
70 inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { 73 inline bool turboSwizzled(J_COLOR_SPACE colorSpace) {
71 return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA; 74 return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA;
72 } 75 }
76 inline bool colorSpaceHasAlpha(J_COLOR_SPACE colorSpace) {
77 return turboSwizzled(colorSpace);
78 }
73 #else 79 #else
74 inline J_COLOR_SPACE rgbOutputColorSpace() { 80 inline J_COLOR_SPACE rgbOutputColorSpace() {
75 return JCS_RGB; 81 return JCS_RGB;
76 } 82 }
83 inline bool colorSpaceHasAlpha(J_COLOR_SPACE) {
84 return false;
85 }
77 #endif 86 #endif
78 87
79 namespace { 88 namespace {
80 89
81 const int exifMarker = JPEG_APP0 + 1; 90 const int exifMarker = JPEG_APP0 + 1;
82 91
83 // JPEG only supports a denominator of 8. 92 // JPEG only supports a denominator of 8.
84 const unsigned scaleDenominator = 8; 93 const unsigned scaleDenominator = 8;
85 94
86 } // namespace 95 } // namespace
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 m_src.pub.fill_input_buffer = fill_input_buffer; 308 m_src.pub.fill_input_buffer = fill_input_buffer;
300 m_src.pub.skip_input_data = skip_input_data; 309 m_src.pub.skip_input_data = skip_input_data;
301 m_src.pub.resync_to_restart = jpeg_resync_to_restart; 310 m_src.pub.resync_to_restart = jpeg_resync_to_restart;
302 m_src.pub.term_source = term_source; 311 m_src.pub.term_source = term_source;
303 m_src.reader = this; 312 m_src.reader = this;
304 313
305 #if USE(ICCJPEG) 314 #if USE(ICCJPEG)
306 // Retain ICC color profile markers for color management. 315 // Retain ICC color profile markers for color management.
307 setup_read_icc_profile(&m_info); 316 setup_read_icc_profile(&m_info);
308 #endif 317 #endif
309
310 // Keep APP1 blocks, for obtaining exif data. 318 // Keep APP1 blocks, for obtaining exif data.
311 jpeg_save_markers(&m_info, exifMarker, 0xFFFF); 319 jpeg_save_markers(&m_info, exifMarker, 0xFFFF);
312 } 320 }
313 321
314 ~JPEGImageReader() { jpeg_destroy_decompress(&m_info); } 322 ~JPEGImageReader() { jpeg_destroy_decompress(&m_info); }
315 323
316 void skipBytes(long numBytes) { 324 void skipBytes(long numBytes) {
317 if (numBytes <= 0) 325 if (numBytes <= 0)
318 return; 326 return;
319 327
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height); 454 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height);
447 455
448 m_decoder->setOrientation(readImageOrientation(info())); 456 m_decoder->setOrientation(readImageOrientation(info()));
449 457
450 // Allow color management of the decoded RGBA pixels if possible. 458 // Allow color management of the decoded RGBA pixels if possible.
451 if (!m_decoder->ignoresGammaAndColorProfile()) { 459 if (!m_decoder->ignoresGammaAndColorProfile()) {
452 #if USE(ICCJPEG) 460 #if USE(ICCJPEG)
453 JOCTET* profile = nullptr; 461 JOCTET* profile = nullptr;
454 unsigned profileLength = 0; 462 unsigned profileLength = 0;
455 if (read_icc_profile(info(), &profile, &profileLength)) { 463 if (read_icc_profile(info(), &profile, &profileLength)) {
456 decoder()->setColorSpaceAndComputeTransform( 464 decoder()->setColorProfileAndComputeTransform(
457 reinterpret_cast<char*>(profile), profileLength, 465 reinterpret_cast<char*>(profile), profileLength,
466 colorSpaceHasAlpha(info()->out_color_space),
458 false /* useSRGB */); 467 false /* useSRGB */);
459 free(profile); 468 free(profile);
460 } 469 }
461 #endif // USE(ICCJPEG) 470 #endif // USE(ICCJPEG)
462 #if USE(SKCOLORXFORM) 471 #if USE(QCMSLIB)
463 if (decoder()->colorTransform()) { 472 if (decoder()->colorTransform()) {
464 overrideColorSpace = JCS_UNKNOWN; 473 overrideColorSpace = JCS_UNKNOWN;
474 #if defined(TURBO_JPEG_RGB_SWIZZLE)
475 // Input RGBA data to qcms. Note: restored to BGRA on output.
476 if (m_info.out_color_space == JCS_EXT_BGRA)
477 m_info.out_color_space = JCS_EXT_RGBA;
478 #endif // defined(TURBO_JPEG_RGB_SWIZZLE)
465 } 479 }
466 #endif // USE(SKCOLORXFORM) 480 #endif // USE(QCMSLIB)
467 } 481 }
468 if (overrideColorSpace == JCS_YCbCr) { 482 if (overrideColorSpace == JCS_YCbCr) {
469 m_info.out_color_space = JCS_YCbCr; 483 m_info.out_color_space = JCS_YCbCr;
470 m_info.raw_data_out = TRUE; 484 m_info.raw_data_out = TRUE;
471 m_uvSize = computeYUVSize( 485 m_uvSize = computeYUVSize(
472 &m_info, 486 &m_info,
473 1); // U size and V size have to be the same if we got here 487 1); // U size and V size have to be the same if we got here
474 } 488 }
475 489
476 // Don't allocate a giant and superfluous memory buffer when the 490 // Don't allocate a giant and superfluous memory buffer when the
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 } 807 }
794 808
795 template <J_COLOR_SPACE colorSpace> 809 template <J_COLOR_SPACE colorSpace>
796 void setPixel(ImageFrame& buffer, 810 void setPixel(ImageFrame& buffer,
797 ImageFrame::PixelData* pixel, 811 ImageFrame::PixelData* pixel,
798 JSAMPARRAY samples, 812 JSAMPARRAY samples,
799 int column) { 813 int column) {
800 ASSERT_NOT_REACHED(); 814 ASSERT_NOT_REACHED();
801 } 815 }
802 816
803 // Used only for debugging with libjpeg (instead of libjpeg-turbo).
804 template <> 817 template <>
805 void setPixel<JCS_RGB>(ImageFrame& buffer, 818 void setPixel<JCS_RGB>(ImageFrame& buffer,
806 ImageFrame::PixelData* pixel, 819 ImageFrame::PixelData* pixel,
807 JSAMPARRAY samples, 820 JSAMPARRAY samples,
808 int column) { 821 int column) {
809 JSAMPLE* jsample = *samples + column * 3; 822 JSAMPLE* jsample = *samples + column * 3;
810 buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255); 823 buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255);
811 } 824 }
812 825
813 template <> 826 template <>
(...skipping 10 matching lines...) Expand all
824 // X = X * (1 - K ) + K [for X = C, M, or Y] 837 // X = X * (1 - K ) + K [for X = C, M, or Y]
825 // Thus, from Inverted CMYK to CMY is: 838 // Thus, from Inverted CMYK to CMY is:
826 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK 839 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
827 // From CMY (0..1) to RGB (0..1): 840 // From CMY (0..1) to RGB (0..1):
828 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] 841 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
829 unsigned k = jsample[3]; 842 unsigned k = jsample[3];
830 buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255, 843 buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255,
831 jsample[2] * k / 255, 255); 844 jsample[2] * k / 255, 255);
832 } 845 }
833 846
834 // Used only for JCS_CMYK and JCS_RGB output. Note that JCS_RGB is used only
835 // for debugging with libjpeg (instead of libjpeg-turbo).
836 template <J_COLOR_SPACE colorSpace> 847 template <J_COLOR_SPACE colorSpace>
837 bool outputRows(JPEGImageReader* reader, ImageFrame& buffer) { 848 bool outputRows(JPEGImageReader* reader, ImageFrame& buffer) {
838 JSAMPARRAY samples = reader->samples(); 849 JSAMPARRAY samples = reader->samples();
839 jpeg_decompress_struct* info = reader->info(); 850 jpeg_decompress_struct* info = reader->info();
840 int width = info->output_width; 851 int width = info->output_width;
841 852
842 while (info->output_scanline < info->output_height) { 853 while (info->output_scanline < info->output_height) {
843 // jpeg_read_scanlines will increase the scanline counter, so we 854 // jpeg_read_scanlines will increase the scanline counter, so we
844 // save the scanline before calling it. 855 // save the scanline before calling it.
845 int y = info->output_scanline; 856 int y = info->output_scanline;
846 // Request one scanline: returns 0 or 1 scanlines. 857 // Request one scanline: returns 0 or 1 scanlines.
847 if (jpeg_read_scanlines(info, samples, 1) != 1) 858 if (jpeg_read_scanlines(info, samples, 1) != 1)
848 return false; 859 return false;
849 860 #if USE(QCMSLIB)
861 if (reader->decoder()->colorTransform() && colorSpace == JCS_RGB)
862 qcms_transform_data(reader->decoder()->colorTransform(), *samples,
863 *samples, width);
864 #endif
850 ImageFrame::PixelData* pixel = buffer.getAddr(0, y); 865 ImageFrame::PixelData* pixel = buffer.getAddr(0, y);
851 for (int x = 0; x < width; ++pixel, ++x) 866 for (int x = 0; x < width; ++pixel, ++x)
852 setPixel<colorSpace>(buffer, pixel, samples, x); 867 setPixel<colorSpace>(buffer, pixel, samples, x);
853
854 #if USE(SKCOLORXFORM)
855 SkColorSpaceXform* xform = reader->decoder()->colorTransform();
856 if (JCS_RGB == colorSpace && xform) {
857 ImageFrame::PixelData* row = buffer.getAddr(0, y);
858 xform->apply(xformColorFormat(), row, xformColorFormat(), row, width,
859 kOpaque_SkAlphaType);
860 }
861 #endif
862 } 868 }
863 869
864 buffer.setPixelsChanged(true); 870 buffer.setPixelsChanged(true);
865 return true; 871 return true;
866 } 872 }
867 873
868 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) { 874 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) {
869 JSAMPARRAY samples = reader->samples(); 875 JSAMPARRAY samples = reader->samples();
870 jpeg_decompress_struct* info = reader->info(); 876 jpeg_decompress_struct* info = reader->info();
871 877
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); 958 buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
953 } 959 }
954 960
955 #if defined(TURBO_JPEG_RGB_SWIZZLE) 961 #if defined(TURBO_JPEG_RGB_SWIZZLE)
956 if (turboSwizzled(info->out_color_space)) { 962 if (turboSwizzled(info->out_color_space)) {
957 while (info->output_scanline < info->output_height) { 963 while (info->output_scanline < info->output_height) {
958 unsigned char* row = reinterpret_cast_ptr<unsigned char*>( 964 unsigned char* row = reinterpret_cast_ptr<unsigned char*>(
959 buffer.getAddr(0, info->output_scanline)); 965 buffer.getAddr(0, info->output_scanline));
960 if (jpeg_read_scanlines(info, &row, 1) != 1) 966 if (jpeg_read_scanlines(info, &row, 1) != 1)
961 return false; 967 return false;
962 968 #if USE(QCMSLIB)
963 #if USE(SKCOLORXFORM) 969 if (qcms_transform* transform = colorTransform())
964 SkColorSpaceXform* xform = colorTransform(); 970 qcms_transform_data_type(transform, row, row, info->output_width,
965 if (xform) { 971 rgbOutputColorSpace() == JCS_EXT_BGRA
966 xform->apply(xformColorFormat(), row, xformColorFormat(), row, 972 ? QCMS_OUTPUT_BGRX
967 info->output_width, kOpaque_SkAlphaType); 973 : QCMS_OUTPUT_RGBX);
968 }
969 #endif 974 #endif
970 } 975 }
971 buffer.setPixelsChanged(true); 976 buffer.setPixelsChanged(true);
972 return true; 977 return true;
973 } 978 }
974 #endif 979 #endif
975 980
976 switch (info->out_color_space) { 981 switch (info->out_color_space) {
977 case JCS_RGB: 982 case JCS_RGB:
978 return outputRows<JCS_RGB>(m_reader.get(), buffer); 983 return outputRows<JCS_RGB>(m_reader.get(), buffer);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 // has failed. 1018 // has failed.
1014 if (!m_reader->decode(onlySize) && isAllDataReceived()) 1019 if (!m_reader->decode(onlySize) && isAllDataReceived())
1015 setFailed(); 1020 setFailed();
1016 1021
1017 // If decoding is done or failed, we don't need the JPEGImageReader anymore. 1022 // If decoding is done or failed, we don't need the JPEGImageReader anymore.
1018 if (isComplete(this, onlySize) || failed()) 1023 if (isComplete(this, onlySize) || failed())
1019 m_reader.reset(); 1024 m_reader.reset();
1020 } 1025 }
1021 1026
1022 } // namespace blink 1027 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698