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

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

Issue 2512683003: Create ImageDecoder target color space (Closed)
Patch Set: Created 4 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) 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 new ICOImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); 114 new ICOImageDecoder(alphaOption, colorOptions, maxDecodedBytes));
115 break; 115 break;
116 case SniffResult::BMP: 116 case SniffResult::BMP:
117 decoder.reset( 117 decoder.reset(
118 new BMPImageDecoder(alphaOption, colorOptions, maxDecodedBytes)); 118 new BMPImageDecoder(alphaOption, colorOptions, maxDecodedBytes));
119 break; 119 break;
120 case SniffResult::Invalid: 120 case SniffResult::Invalid:
121 break; 121 break;
122 } 122 }
123 123
124 if (decoder) 124 if (decoder) {
125 decoder->setData(data.release(), dataComplete); 125 decoder->setData(data.release(), dataComplete);
126 decoder->m_targetColorSpace = globalTargetColorSpace();
127 }
126 128
127 return decoder; 129 return decoder;
128 } 130 }
129 131
130 bool ImageDecoder::hasSufficientDataToSniffImageType(const SharedBuffer& data) { 132 bool ImageDecoder::hasSufficientDataToSniffImageType(const SharedBuffer& data) {
131 return data.size() >= kLongestSignatureLength; 133 return data.size() >= kLongestSignatureLength;
132 } 134 }
133 135
134 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents, 136 ImageDecoder::SniffResult ImageDecoder::determineImageType(const char* contents,
135 size_t length) { 137 size_t length) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 369
368 namespace { 370 namespace {
369 371
370 // The output device color space is global and shared across multiple threads. 372 // The output device color space is global and shared across multiple threads.
371 SpinLock gTargetColorSpaceLock; 373 SpinLock gTargetColorSpaceLock;
372 SkColorSpace* gTargetColorSpace = nullptr; 374 SkColorSpace* gTargetColorSpace = nullptr;
373 375
374 } // namespace 376 } // namespace
375 377
376 // static 378 // static
377 void ImageDecoder::setTargetColorProfile(const WebVector<char>& profile) { 379 void ImageDecoder::setGlobalTargetColorProfile(const WebVector<char>& profile) {
378 if (profile.isEmpty()) 380 if (profile.isEmpty())
379 return; 381 return;
380 382
381 // Take a lock around initializing and accessing the global device color 383 // Take a lock around initializing and accessing the global device color
382 // profile. 384 // profile.
383 SpinLock::Guard guard(gTargetColorSpaceLock); 385 SpinLock::Guard guard(gTargetColorSpaceLock);
384 386
385 // Layout tests expect that only the first call will take effect. 387 // Layout tests expect that only the first call will take effect.
386 if (gTargetColorSpace) 388 if (gTargetColorSpace)
387 return; 389 return;
388 390
389 gTargetColorSpace = 391 gTargetColorSpace =
390 SkColorSpace::MakeICC(profile.data(), profile.size()).release(); 392 SkColorSpace::MakeICC(profile.data(), profile.size()).release();
391 393
392 // UMA statistics. 394 // UMA statistics.
393 BitmapImageMetrics::countOutputGamma(gTargetColorSpace); 395 BitmapImageMetrics::countOutputGamma(gTargetColorSpace);
394 } 396 }
395 397
398 // static
399 sk_sp<SkColorSpace> ImageDecoder::globalTargetColorSpace() {
400 // Take a lock around initializing and accessing the global device color
401 // profile.
402 SpinLock::Guard guard(gTargetColorSpaceLock);
403
404 // Initialize the output device profile to sRGB if it has not yet been
405 // initialized.
406 if (!gTargetColorSpace) {
407 gTargetColorSpace =
408 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).release();
409 }
410
411 gTargetColorSpace->ref();
412 return sk_sp<SkColorSpace>(gTargetColorSpace);
413 }
414
396 sk_sp<SkColorSpace> ImageDecoder::colorSpace() const { 415 sk_sp<SkColorSpace> ImageDecoder::colorSpace() const {
397 // TODO(ccameron): This should always return a non-null SkColorSpace. This is 416 // TODO(ccameron): This should always return a non-null SkColorSpace. This is
398 // disabled for now because specifying a non-renderable color space results in 417 // disabled for now because specifying a non-renderable color space results in
399 // errors. 418 // errors.
400 // https://bugs.chromium.org/p/skia/issues/detail?id=5907 419 // https://bugs.chromium.org/p/skia/issues/detail?id=5907
401 if (!RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) 420 if (!RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
402 return nullptr; 421 return nullptr;
403 422
404 if (m_embeddedColorSpace) 423 if (m_embeddedColorSpace)
405 return m_embeddedColorSpace; 424 return m_embeddedColorSpace;
406 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); 425 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
407 } 426 }
408 427
409 void ImageDecoder::setColorProfileAndComputeTransform(const char* iccData, 428 void ImageDecoder::setEmbeddedColorProfile(const char* iccData,
410 unsigned iccLength) { 429 unsigned iccLength) {
411 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength); 430 sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(iccData, iccLength);
412 if (!colorSpace) 431 if (!colorSpace)
413 DLOG(ERROR) << "Failed to parse image ICC profile"; 432 DLOG(ERROR) << "Failed to parse image ICC profile";
414 setColorSpaceAndComputeTransform(std::move(colorSpace)); 433 setEmbeddedColorSpace(std::move(colorSpace));
415 } 434 }
416 435
417 void ImageDecoder::setColorSpaceAndComputeTransform( 436 void ImageDecoder::setEmbeddedColorSpace(sk_sp<SkColorSpace> colorSpace) {
418 sk_sp<SkColorSpace> colorSpace) {
419 DCHECK(!m_ignoreColorSpace); 437 DCHECK(!m_ignoreColorSpace);
420 DCHECK(!m_hasHistogrammedColorSpace); 438 DCHECK(!m_hasHistogrammedColorSpace);
421 439
422 m_embeddedColorSpace = colorSpace; 440 m_embeddedColorSpace = colorSpace;
441 m_sourceToTargetColorTransformNeedsUpdate = true;
442 }
423 443
424 m_sourceToOutputDeviceColorTransform = nullptr; 444 SkColorSpaceXform* ImageDecoder::colorTransform() {
445 if (!m_sourceToTargetColorTransformNeedsUpdate)
446 return m_sourceToTargetColorTransform.get();
447 m_sourceToTargetColorTransformNeedsUpdate = false;
448 m_sourceToTargetColorTransform = nullptr;
425 449
426 // With color correct rendering, we do not transform to the output color space 450 // With color correct rendering, we do not transform to the output color space
427 // at decode time. Instead, we tag the raw image pixels and pass the tagged 451 // at decode time. Instead, we tag the raw image pixels and pass the tagged
428 // SkImage to Skia. 452 // SkImage to Skia.
429 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) 453 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
430 return; 454 return nullptr;
431 455
432 if (!m_embeddedColorSpace) 456 if (!m_embeddedColorSpace)
433 return; 457 return nullptr;
434 458
435 // Take a lock around initializing and accessing the global device color 459 if (SkColorSpace::Equals(m_embeddedColorSpace.get(),
436 // profile. 460 m_targetColorSpace.get())) {
437 SpinLock::Guard guard(gTargetColorSpaceLock); 461 return nullptr;
438
439 // Initialize the output device profile to sRGB if it has not yet been
440 // initialized.
441 if (!gTargetColorSpace) {
442 gTargetColorSpace =
443 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).release();
444 } 462 }
445 463
446 if (SkColorSpace::Equals(m_embeddedColorSpace.get(), gTargetColorSpace)) { 464 m_sourceToTargetColorTransform = SkColorSpaceXform::New(
447 return; 465 m_embeddedColorSpace.get(), m_targetColorSpace.get());
448 } 466 return m_sourceToTargetColorTransform.get();
449
450 m_sourceToOutputDeviceColorTransform =
451 SkColorSpaceXform::New(m_embeddedColorSpace.get(), gTargetColorSpace);
452 } 467 }
453 468
454 } // namespace blink 469 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698