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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/BitmapImage.cpp

Issue 2556973002: Allow specifying ColorBehavior to ImageSource (Closed)
Patch Set: Rebase 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) 2006 Samuel Weinig (sam.weinig@gmail.com) 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "platform/graphics/BitmapImage.h" 27 #include "platform/graphics/BitmapImage.h"
28 28
29 #include "platform/PlatformInstrumentation.h" 29 #include "platform/PlatformInstrumentation.h"
30 #include "platform/RuntimeEnabledFeatures.h"
30 #include "platform/Timer.h" 31 #include "platform/Timer.h"
31 #include "platform/geometry/FloatRect.h" 32 #include "platform/geometry/FloatRect.h"
32 #include "platform/graphics/BitmapImageMetrics.h" 33 #include "platform/graphics/BitmapImageMetrics.h"
33 #include "platform/graphics/DeferredImageDecoder.h" 34 #include "platform/graphics/DeferredImageDecoder.h"
34 #include "platform/graphics/ImageObserver.h" 35 #include "platform/graphics/ImageObserver.h"
35 #include "platform/graphics/StaticBitmapImage.h" 36 #include "platform/graphics/StaticBitmapImage.h"
36 #include "platform/graphics/skia/SkiaUtils.h" 37 #include "platform/graphics/skia/SkiaUtils.h"
37 #include "platform/tracing/TraceEvent.h" 38 #include "platform/tracing/TraceEvent.h"
38 #include "third_party/skia/include/core/SkCanvas.h" 39 #include "third_party/skia/include/core/SkCanvas.h"
39 #include "wtf/PassRefPtr.h" 40 #include "wtf/PassRefPtr.h"
40 #include "wtf/PtrUtil.h" 41 #include "wtf/PtrUtil.h"
41 #include "wtf/text/WTFString.h" 42 #include "wtf/text/WTFString.h"
42 43
43 namespace blink { 44 namespace blink {
44 45
46 namespace {
47
48 ColorBehavior defaultColorBehavior() {
49 // TODO(ccameron): ColorBehavior should be specified by the caller requesting
50 // SkImages.
51 // https://crbug.com/667420
52 if (RuntimeEnabledFeatures::trueColorRenderingEnabled())
53 return ColorBehavior::tag();
54 return ColorBehavior::transformToGlobalTarget();
55 }
56
57 } // namespace
58
45 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting( 59 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(
46 const SkBitmap& bitmap, 60 const SkBitmap& bitmap,
47 ImageOrientation orientation) { 61 ImageOrientation orientation) {
48 if (bitmap.isNull()) { 62 if (bitmap.isNull()) {
49 return BitmapImage::create(); 63 return BitmapImage::create();
50 } 64 }
51 65
52 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); 66 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap));
53 result->m_frames[0].m_orientation = orientation; 67 result->m_frames[0].m_orientation = orientation;
54 if (orientation.usesWidthAsHeight()) 68 if (orientation.usesWidthAsHeight())
55 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); 69 result->m_sizeRespectingOrientation = result->m_size.transposedSize();
56 return result.release(); 70 return result.release();
57 } 71 }
58 72
59 BitmapImage::BitmapImage(ImageObserver* observer) 73 BitmapImage::BitmapImage(ImageObserver* observer)
60 : Image(observer), 74 : Image(observer),
61 m_currentFrame(0), 75 m_currentFrame(0),
62 m_cachedFrameIndex(0), 76 m_cachedFrameIndex(0),
77 m_cachedFrameColorBehavior(defaultColorBehavior()),
63 m_repetitionCount(cAnimationNone), 78 m_repetitionCount(cAnimationNone),
64 m_repetitionCountStatus(Unknown), 79 m_repetitionCountStatus(Unknown),
65 m_repetitionsComplete(0), 80 m_repetitionsComplete(0),
66 m_desiredFrameStartTime(0), 81 m_desiredFrameStartTime(0),
67 m_frameCount(0), 82 m_frameCount(0),
68 m_animationPolicy(ImageAnimationPolicyAllowed), 83 m_animationPolicy(ImageAnimationPolicyAllowed),
69 m_animationFinished(false), 84 m_animationFinished(false),
70 m_allDataReceived(false), 85 m_allDataReceived(false),
71 m_haveSize(false), 86 m_haveSize(false),
72 m_sizeAvailable(false), 87 m_sizeAvailable(false),
73 m_haveFrameCount(false) {} 88 m_haveFrameCount(false) {}
74 89
75 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) 90 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer)
76 : Image(observer), 91 : Image(observer),
77 m_size(bitmap.width(), bitmap.height()), 92 m_size(bitmap.width(), bitmap.height()),
78 m_currentFrame(0), 93 m_currentFrame(0),
79 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)), 94 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)),
80 m_cachedFrameIndex(0), 95 m_cachedFrameIndex(0),
96 m_cachedFrameColorBehavior(defaultColorBehavior()),
81 m_repetitionCount(cAnimationNone), 97 m_repetitionCount(cAnimationNone),
82 m_repetitionCountStatus(Unknown), 98 m_repetitionCountStatus(Unknown),
83 m_repetitionsComplete(0), 99 m_repetitionsComplete(0),
84 m_frameCount(1), 100 m_frameCount(1),
85 m_animationPolicy(ImageAnimationPolicyAllowed), 101 m_animationPolicy(ImageAnimationPolicyAllowed),
86 m_animationFinished(true), 102 m_animationFinished(true),
87 m_allDataReceived(true), 103 m_allDataReceived(true),
88 m_haveSize(true), 104 m_haveSize(true),
89 m_sizeAvailable(true), 105 m_sizeAvailable(true),
90 m_haveFrameCount(true) { 106 m_haveFrameCount(true) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 139 }
124 140
125 size_t BitmapImage::totalFrameBytes() { 141 size_t BitmapImage::totalFrameBytes() {
126 const size_t numFrames = frameCount(); 142 const size_t numFrames = frameCount();
127 size_t totalBytes = 0; 143 size_t totalBytes = 0;
128 for (size_t i = 0; i < numFrames; ++i) 144 for (size_t i = 0; i < numFrames; ++i)
129 totalBytes += m_source.frameBytesAtIndex(i); 145 totalBytes += m_source.frameBytesAtIndex(i);
130 return totalBytes; 146 return totalBytes;
131 } 147 }
132 148
133 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame(size_t index) { 149 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame(
150 size_t index,
151 const ColorBehavior& colorBehavior) {
134 size_t numFrames = frameCount(); 152 size_t numFrames = frameCount();
135 if (m_frames.size() < numFrames) 153 if (m_frames.size() < numFrames)
136 m_frames.grow(numFrames); 154 m_frames.grow(numFrames);
137 155
138 // We are caching frame snapshots. This is OK even for partially decoded 156 // We are caching frame snapshots. This is OK even for partially decoded
139 // frames, as they are cleared by dataChanged() when new data arrives. 157 // frames, as they are cleared by dataChanged() when new data arrives.
140 sk_sp<SkImage> image = m_source.createFrameAtIndex(index); 158 sk_sp<SkImage> image = m_source.createFrameAtIndex(index, colorBehavior);
141 m_cachedFrame = image; 159 m_cachedFrame = image;
142 m_cachedFrameIndex = index; 160 m_cachedFrameIndex = index;
161 m_cachedFrameColorBehavior = colorBehavior;
143 162
144 m_frames[index].m_orientation = m_source.orientationAtIndex(index); 163 m_frames[index].m_orientation = m_source.orientationAtIndex(index);
145 m_frames[index].m_haveMetadata = true; 164 m_frames[index].m_haveMetadata = true;
146 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); 165 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
147 if (repetitionCount(false) != cAnimationNone) 166 if (repetitionCount(false) != cAnimationNone)
148 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); 167 m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
149 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); 168 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
150 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); 169 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);
151 170
152 notifyMemoryChanged(); 171 notifyMemoryChanged();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 if (m_sizeAvailable && hasVisibleImageSize(size())) { 336 if (m_sizeAvailable && hasVisibleImageSize(size())) {
318 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); 337 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension());
319 if (m_source.filenameExtension() == "jpg") 338 if (m_source.filenameExtension() == "jpg")
320 BitmapImageMetrics::countImageOrientation( 339 BitmapImageMetrics::countImageOrientation(
321 m_source.orientationAtIndex(0).orientation()); 340 m_source.orientationAtIndex(0).orientation());
322 } 341 }
323 342
324 return m_sizeAvailable; 343 return m_sizeAvailable;
325 } 344 }
326 345
327 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index) { 346 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index,
347 const ColorBehavior& colorBehavior) {
328 if (index >= frameCount()) 348 if (index >= frameCount())
329 return nullptr; 349 return nullptr;
330 350
331 if (index == m_cachedFrameIndex && m_cachedFrame) 351 if (index == m_cachedFrameIndex && m_cachedFrame &&
352 m_cachedFrameColorBehavior == colorBehavior)
332 return m_cachedFrame; 353 return m_cachedFrame;
333 354
334 return decodeAndCacheFrame(index); 355 return decodeAndCacheFrame(index, colorBehavior);
335 } 356 }
336 357
337 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const { 358 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const {
338 if (index < m_frames.size() && m_frames[index].m_haveMetadata && 359 if (index < m_frames.size() && m_frames[index].m_haveMetadata &&
339 m_frames[index].m_isComplete) 360 m_frames[index].m_isComplete)
340 return true; 361 return true;
341 362
342 return m_source.frameIsCompleteAtIndex(index); 363 return m_source.frameIsCompleteAtIndex(index);
343 } 364 }
344 365
345 float BitmapImage::frameDurationAtIndex(size_t index) const { 366 float BitmapImage::frameDurationAtIndex(size_t index) const {
346 if (index < m_frames.size() && m_frames[index].m_haveMetadata) 367 if (index < m_frames.size() && m_frames[index].m_haveMetadata)
347 return m_frames[index].m_duration; 368 return m_frames[index].m_duration;
348 369
349 return m_source.frameDurationAtIndex(index); 370 return m_source.frameDurationAtIndex(index);
350 } 371 }
351 372
352 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() { 373 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() {
353 return frameAtIndex(currentFrame()); 374 // TODO(ccameron): Allow the caller of imageForCurrentFrame to specify the
375 // the desired ColorBehavior.
376 // https://crbug.com/667420
377 const ColorBehavior& colorBehavior = m_cachedFrameColorBehavior;
378 return frameAtIndex(currentFrame(), colorBehavior);
354 } 379 }
355 380
356 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() { 381 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() {
382 // TODO(ccameron): Determine the appropriate ColorBehavior for this situation.
383 // https://crbug.com/667420
384 const ColorBehavior& colorBehavior = m_cachedFrameColorBehavior;
357 if (frameCount() > 1) { 385 if (frameCount() > 1) {
358 sk_sp<SkImage> firstFrame = frameAtIndex(0); 386 sk_sp<SkImage> firstFrame = frameAtIndex(0, colorBehavior);
359 if (firstFrame) 387 if (firstFrame)
360 return StaticBitmapImage::create(std::move(firstFrame)); 388 return StaticBitmapImage::create(std::move(firstFrame));
361 } 389 }
362 390
363 return Image::imageForDefaultFrame(); 391 return Image::imageForDefaultFrame();
364 } 392 }
365 393
366 bool BitmapImage::frameHasAlphaAtIndex(size_t index) { 394 bool BitmapImage::frameHasAlphaAtIndex(size_t index) {
367 if (m_frames.size() <= index) 395 if (m_frames.size() <= index)
368 return true; 396 return true;
369 397
370 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) 398 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha)
371 return false; 399 return false;
372 400
373 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask 401 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask
374 // ImageSource for the value if the cached value is the default value. 402 // ImageSource for the value if the cached value is the default value.
375 bool hasAlpha = m_source.frameHasAlphaAtIndex(index); 403 bool hasAlpha = m_source.frameHasAlphaAtIndex(index);
376 404
377 if (m_frames[index].m_haveMetadata) 405 if (m_frames[index].m_haveMetadata)
378 m_frames[index].m_hasAlpha = hasAlpha; 406 m_frames[index].m_hasAlpha = hasAlpha;
379 407
380 return hasAlpha; 408 return hasAlpha;
381 } 409 }
382 410
383 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) { 411 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) {
384 if (metadataMode == PreCacheMetadata) { 412 if (metadataMode == PreCacheMetadata) {
385 // frameHasAlphaAtIndex() conservatively returns false for uncached frames. 413 // frameHasAlphaAtIndex() conservatively returns false for uncached frames.
386 // To increase the chance of an accurate answer, pre-cache the current frame 414 // To increase the chance of an accurate answer, pre-cache the current frame
387 // metadata. 415 // metadata. Because ColorBehavior does not affect this result, use
388 frameAtIndex(currentFrame()); 416 // whatever ColorBehavior was last used (if any).
417 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior);
389 } 418 }
390 return !frameHasAlphaAtIndex(currentFrame()); 419 return !frameHasAlphaAtIndex(currentFrame());
391 } 420 }
392 421
393 bool BitmapImage::currentFrameIsComplete() { 422 bool BitmapImage::currentFrameIsComplete() {
394 return frameIsCompleteAtIndex(currentFrame()); 423 return frameIsCompleteAtIndex(currentFrame());
395 } 424 }
396 425
397 bool BitmapImage::currentFrameIsLazyDecoded() { 426 bool BitmapImage::currentFrameIsLazyDecoded() {
398 sk_sp<SkImage> image = frameAtIndex(currentFrame()); 427 // Because ColorBehavior does not affect this result, use whatever
428 // ColorBehavior was last used (if any).
429 sk_sp<SkImage> image =
430 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior);
399 return image && image->isLazyGenerated(); 431 return image && image->isLazyGenerated();
400 } 432 }
401 433
402 ImageOrientation BitmapImage::currentFrameOrientation() { 434 ImageOrientation BitmapImage::currentFrameOrientation() {
403 return frameOrientationAtIndex(currentFrame()); 435 return frameOrientationAtIndex(currentFrame());
404 } 436 }
405 437
406 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) { 438 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) {
407 if (m_frames.size() <= index) 439 if (m_frames.size() <= index)
408 return DefaultImageOrientation; 440 return DefaultImageOrientation;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 getImageObserver()->animationAdvanced(this); 653 getImageObserver()->animationAdvanced(this);
622 654
623 return true; 655 return true;
624 } 656 }
625 657
626 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) { 658 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) {
627 getImageObserver()->animationAdvanced(this); 659 getImageObserver()->animationAdvanced(this);
628 } 660 }
629 661
630 } // namespace blink 662 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698