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

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

Issue 2556723003: Merge color options into ColorBehavior (Closed)
Patch Set: Feedback Created 4 years 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) Research In Motion Limited 2009-2010. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 64 }
65 65
66 // This needs to be updated if we ever add a matches*Signature() which requires 66 // This needs to be updated if we ever add a matches*Signature() which requires
67 // more characters. 67 // more characters.
68 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1; 68 static constexpr size_t kLongestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
69 69
70 std::unique_ptr<ImageDecoder> ImageDecoder::create( 70 std::unique_ptr<ImageDecoder> ImageDecoder::create(
71 PassRefPtr<SegmentReader> passData, 71 PassRefPtr<SegmentReader> passData,
72 bool dataComplete, 72 bool dataComplete,
73 AlphaOption alphaOption, 73 AlphaOption alphaOption,
74 ColorSpaceOption colorOptions, 74 const ColorBehavior& colorBehavior) {
75 sk_sp<SkColorSpace> targetColorSpace) {
76 RefPtr<SegmentReader> data = passData; 75 RefPtr<SegmentReader> data = passData;
77 76
78 // Ensure that the color space options are consistent.
79 if (colorOptions == ColorSpaceTransformed)
80 DCHECK(targetColorSpace);
81 else
82 DCHECK(!targetColorSpace);
83
84 // We need at least kLongestSignatureLength bytes to run the signature 77 // We need at least kLongestSignatureLength bytes to run the signature
85 // matcher. 78 // matcher.
86 if (data->size() < kLongestSignatureLength) 79 if (data->size() < kLongestSignatureLength)
87 return nullptr; 80 return nullptr;
88 81
89 const size_t maxDecodedBytes = 82 const size_t maxDecodedBytes =
90 Platform::current() ? Platform::current()->maxDecodedImageBytes() 83 Platform::current() ? Platform::current()->maxDecodedImageBytes()
91 : noDecodedImageByteLimit; 84 : noDecodedImageByteLimit;
92 85
93 // Access the first kLongestSignatureLength chars to sniff the signature. 86 // Access the first kLongestSignatureLength chars to sniff the signature.
94 // (note: FastSharedBufferReader only makes a copy if the bytes are segmented) 87 // (note: FastSharedBufferReader only makes a copy if the bytes are segmented)
95 char buffer[kLongestSignatureLength]; 88 char buffer[kLongestSignatureLength];
96 const FastSharedBufferReader fastReader(data); 89 const FastSharedBufferReader fastReader(data);
97 const ImageDecoder::SniffResult sniffResult = determineImageType( 90 const ImageDecoder::SniffResult sniffResult = determineImageType(
98 fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer), 91 fastReader.getConsecutiveData(0, kLongestSignatureLength, buffer),
99 kLongestSignatureLength); 92 kLongestSignatureLength);
100 93
101 std::unique_ptr<ImageDecoder> decoder; 94 std::unique_ptr<ImageDecoder> decoder;
102 switch (sniffResult) { 95 switch (sniffResult) {
103 case SniffResult::JPEG: 96 case SniffResult::JPEG:
104 decoder.reset(new JPEGImageDecoder(alphaOption, colorOptions, 97 decoder.reset(
105 std::move(targetColorSpace), 98 new JPEGImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
106 maxDecodedBytes));
107 break; 99 break;
108 case SniffResult::PNG: 100 case SniffResult::PNG:
109 decoder.reset(new PNGImageDecoder(alphaOption, colorOptions, 101 decoder.reset(
110 std::move(targetColorSpace), 102 new PNGImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
111 maxDecodedBytes));
112 break; 103 break;
113 case SniffResult::GIF: 104 case SniffResult::GIF:
114 decoder.reset(new GIFImageDecoder(alphaOption, colorOptions, 105 decoder.reset(
115 std::move(targetColorSpace), 106 new GIFImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
116 maxDecodedBytes));
117 break; 107 break;
118 case SniffResult::WEBP: 108 case SniffResult::WEBP:
119 decoder.reset(new WEBPImageDecoder(alphaOption, colorOptions, 109 decoder.reset(
120 std::move(targetColorSpace), 110 new WEBPImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
121 maxDecodedBytes));
122 break; 111 break;
123 case SniffResult::ICO: 112 case SniffResult::ICO:
124 decoder.reset(new ICOImageDecoder(alphaOption, colorOptions, 113 decoder.reset(
125 std::move(targetColorSpace), 114 new ICOImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
126 maxDecodedBytes));
127 break; 115 break;
128 case SniffResult::BMP: 116 case SniffResult::BMP:
129 decoder.reset(new BMPImageDecoder(alphaOption, colorOptions, 117 decoder.reset(
130 std::move(targetColorSpace), 118 new BMPImageDecoder(alphaOption, colorBehavior, maxDecodedBytes));
131 maxDecodedBytes));
132 break; 119 break;
133 case SniffResult::Invalid: 120 case SniffResult::Invalid:
134 break; 121 break;
135 } 122 }
136 123
137 if (decoder) 124 if (decoder)
138 decoder->setData(data.release(), dataComplete); 125 decoder->setData(data.release(), dataComplete);
139 126
140 return decoder; 127 return decoder;
141 } 128 }
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 void* ImagePlanes::plane(int i) { 489 void* ImagePlanes::plane(int i) {
503 ASSERT((i >= 0) && i < 3); 490 ASSERT((i >= 0) && i < 3);
504 return m_planes[i]; 491 return m_planes[i];
505 } 492 }
506 493
507 size_t ImagePlanes::rowBytes(int i) const { 494 size_t ImagePlanes::rowBytes(int i) const {
508 ASSERT((i >= 0) && i < 3); 495 ASSERT((i >= 0) && i < 3);
509 return m_rowBytes[i]; 496 return m_rowBytes[i];
510 } 497 }
511 498
512 namespace {
513
514 // The output device color space is global and shared across multiple threads.
515 SpinLock gTargetColorSpaceLock;
516 SkColorSpace* gTargetColorSpace = nullptr;
517
518 } // namespace
519
520 // static
521 void ImageDecoder::setGlobalTargetColorProfile(const WebVector<char>& profile) {
522 if (profile.isEmpty())
523 return;
524
525 // Take a lock around initializing and accessing the global device color
526 // profile.
527 SpinLock::Guard guard(gTargetColorSpaceLock);
528
529 // Layout tests expect that only the first call will take effect.
530 if (gTargetColorSpace)
531 return;
532
533 gTargetColorSpace =
534 SkColorSpace::MakeICC(profile.data(), profile.size()).release();
535
536 // UMA statistics.
537 BitmapImageMetrics::countOutputGamma(gTargetColorSpace);
538 }
539
540 // static
541 sk_sp<SkColorSpace> ImageDecoder::globalTargetColorSpace() {
542 // Take a lock around initializing and accessing the global device color
543 // profile.
544 SpinLock::Guard guard(gTargetColorSpaceLock);
545
546 // Initialize the output device profile to sRGB if it has not yet been
547 // initialized.
548 if (!gTargetColorSpace) {
549 gTargetColorSpace =
550 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).release();
551 }
552
553 gTargetColorSpace->ref();
554 return sk_sp<SkColorSpace>(gTargetColorSpace);
555 }
556
557 // static
558 sk_sp<SkColorSpace> ImageDecoder::targetColorSpaceForTesting() {
559 return globalTargetColorSpace();
560 }
561
562 sk_sp<SkColorSpace> ImageDecoder::colorSpaceForSkImages() const {
563 if (m_colorSpaceOption != ColorSpaceTagged)
564 return nullptr;
565
566 if (m_embeddedColorSpace)
567 return m_embeddedColorSpace;
568 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
569 }
570
571 void ImageDecoder::setEmbeddedColorProfile(const char* iccData, 499 void ImageDecoder::setEmbeddedColorProfile(const char* iccData,
572 unsigned iccLength) { 500 unsigned iccLength) {
573 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength); 501 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength);
574 if (!colorSpace) 502 if (!colorSpace)
575 DLOG(ERROR) << "Failed to parse image ICC profile"; 503 DLOG(ERROR) << "Failed to parse image ICC profile";
576 setEmbeddedColorSpace(std::move(colorSpace)); 504 setEmbeddedColorSpace(std::move(colorSpace));
577 } 505 }
578 506
579 void ImageDecoder::setEmbeddedColorSpace(sk_sp<SkColorSpace> colorSpace) { 507 void ImageDecoder::setEmbeddedColorSpace(sk_sp<SkColorSpace> colorSpace) {
580 DCHECK(!ignoresColorSpace()); 508 DCHECK(!ignoresColorSpace());
581 DCHECK(!m_hasHistogrammedColorSpace); 509 DCHECK(!m_hasHistogrammedColorSpace);
582 510
583 m_embeddedColorSpace = colorSpace; 511 m_embeddedColorSpace = colorSpace;
584 m_sourceToTargetColorTransformNeedsUpdate = true; 512 m_sourceToTargetColorTransformNeedsUpdate = true;
585 } 513 }
586 514
587 SkColorSpaceXform* ImageDecoder::colorTransform() { 515 SkColorSpaceXform* ImageDecoder::colorTransform() {
588 if (!m_sourceToTargetColorTransformNeedsUpdate) 516 if (!m_sourceToTargetColorTransformNeedsUpdate)
589 return m_sourceToTargetColorTransform.get(); 517 return m_sourceToTargetColorTransform.get();
590 m_sourceToTargetColorTransformNeedsUpdate = false; 518 m_sourceToTargetColorTransformNeedsUpdate = false;
591 m_sourceToTargetColorTransform = nullptr; 519 m_sourceToTargetColorTransform = nullptr;
592 520
593 // With color correct rendering, we do not transform to the output color space 521 if (!m_colorBehavior.isTransformToTargetColorSpace())
594 // at decode time. Instead, we tag the raw image pixels and pass the tagged
595 // SkImage to Skia.
596 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
597 return nullptr; 522 return nullptr;
598 523
599 if (!m_embeddedColorSpace) 524 sk_sp<SkColorSpace> srcColorSpace = m_embeddedColorSpace;
600 return nullptr; 525 if (!srcColorSpace) {
526 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
527 srcColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
528 else
529 return nullptr;
530 }
601 531
602 if (SkColorSpace::Equals(m_embeddedColorSpace.get(), 532 if (SkColorSpace::Equals(m_embeddedColorSpace.get(),
603 m_targetColorSpace.get())) { 533 m_colorBehavior.targetColorSpace().get())) {
604 return nullptr; 534 return nullptr;
605 } 535 }
606 536
607 m_sourceToTargetColorTransform = SkColorSpaceXform::New( 537 m_sourceToTargetColorTransform = SkColorSpaceXform::New(
608 m_embeddedColorSpace.get(), m_targetColorSpace.get()); 538 m_embeddedColorSpace.get(), m_colorBehavior.targetColorSpace().get());
609 return m_sourceToTargetColorTransform.get(); 539 return m_sourceToTargetColorTransform.get();
610 } 540 }
611 541
542 sk_sp<SkColorSpace> ImageDecoder::colorSpaceForSkImages() const {
543 if (!m_colorBehavior.isTag())
544 return nullptr;
545
546 if (m_embeddedColorSpace)
547 return m_embeddedColorSpace;
548 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
549 }
550
612 } // namespace blink 551 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698