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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/ImageDecoder.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) 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 17 matching lines...) Expand all
28 #include "platform/image-decoders/gif/GIFImageDecoder.h" 28 #include "platform/image-decoders/gif/GIFImageDecoder.h"
29 #include "platform/image-decoders/ico/ICOImageDecoder.h" 29 #include "platform/image-decoders/ico/ICOImageDecoder.h"
30 #include "platform/image-decoders/jpeg/JPEGImageDecoder.h" 30 #include "platform/image-decoders/jpeg/JPEGImageDecoder.h"
31 #include "platform/image-decoders/png/PNGImageDecoder.h" 31 #include "platform/image-decoders/png/PNGImageDecoder.h"
32 #include "platform/image-decoders/webp/WEBPImageDecoder.h" 32 #include "platform/image-decoders/webp/WEBPImageDecoder.h"
33 #include "wtf/PtrUtil.h" 33 #include "wtf/PtrUtil.h"
34 #include <memory> 34 #include <memory>
35 35
36 namespace blink { 36 namespace blink {
37 37
38 #if USE(QCMSLIB)
39 struct QCMSProfileDeleter {
40 void operator()(qcms_profile* profile) {
41 if (profile)
42 qcms_profile_release(profile);
43 }
44 };
45
46 using QCMSProfileUniquePtr = std::unique_ptr<qcms_profile, QCMSProfileDeleter>;
47 #endif // USE(QCMSLIB)
48
38 inline bool matchesJPEGSignature(const char* contents) { 49 inline bool matchesJPEGSignature(const char* contents) {
39 return !memcmp(contents, "\xFF\xD8\xFF", 3); 50 return !memcmp(contents, "\xFF\xD8\xFF", 3);
40 } 51 }
41 52
42 inline bool matchesPNGSignature(const char* contents) { 53 inline bool matchesPNGSignature(const char* contents) {
43 return !memcmp(contents, "\x89PNG\r\n\x1A\n", 8); 54 return !memcmp(contents, "\x89PNG\r\n\x1A\n", 8);
44 } 55 }
45 56
46 inline bool matchesGIFSignature(const char* contents) { 57 inline bool matchesGIFSignature(const char* contents) {
47 return !memcmp(contents, "GIF87a", 6) || !memcmp(contents, "GIF89a", 6); 58 return !memcmp(contents, "GIF87a", 6) || !memcmp(contents, "GIF89a", 6);
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 return m_planes[i]; 336 return m_planes[i];
326 } 337 }
327 338
328 size_t ImagePlanes::rowBytes(int i) const { 339 size_t ImagePlanes::rowBytes(int i) const {
329 ASSERT((i >= 0) && i < 3); 340 ASSERT((i >= 0) && i < 3);
330 return m_rowBytes[i]; 341 return m_rowBytes[i];
331 } 342 }
332 343
333 namespace { 344 namespace {
334 345
335 #if USE(SKCOLORXFORM) 346 #if USE(QCMSLIB)
336 347
337 // The output device color space is global and shared across multiple threads. 348 const unsigned kIccColorProfileHeaderLength = 128;
338 SpinLock gTargetColorSpaceLock;
339 SkColorSpace* gTargetColorSpace = nullptr;
340 349
341 #endif // USE(SKCOLORXFORM) 350 bool rgbColorProfile(const char* profileData, unsigned profileLength) {
351 DCHECK_GE(profileLength, kIccColorProfileHeaderLength);
352
353 return !memcmp(&profileData[16], "RGB ", 4);
354 }
355
356 bool inputDeviceColorProfile(const char* profileData, unsigned profileLength) {
357 DCHECK_GE(profileLength, kIccColorProfileHeaderLength);
358
359 return !memcmp(&profileData[12], "mntr", 4) ||
360 !memcmp(&profileData[12], "scnr", 4);
361 }
362
363 // The output device color profile is global and shared across multiple threads.
364 SpinLock gTargetColorProfileLock;
365 qcms_profile* gTargetColorProfile = nullptr;
366
367 #endif // USE(QCMSLIB)
342 368
343 } // namespace 369 } // namespace
344 370
345 // static 371 // static
346 void ImageDecoder::setTargetColorProfile(const WebVector<char>& profile) { 372 void ImageDecoder::setTargetColorProfile(const WebVector<char>& profile) {
347 #if USE(SKCOLORXFORM) 373 #if USE(QCMSLIB)
348 if (profile.isEmpty()) 374 if (profile.isEmpty())
349 return; 375 return;
350 376
351 // Take a lock around initializing and accessing the global device color 377 // Take a lock around initializing and accessing the global device color
352 // profile. 378 // profile.
353 SpinLock::Guard guard(gTargetColorSpaceLock); 379 SpinLock::Guard guard(gTargetColorProfileLock);
354 380
355 // Layout tests expect that only the first call will take effect. 381 // Layout tests expect that only the first call will take effect.
356 if (gTargetColorSpace) 382 if (gTargetColorProfile)
357 return; 383 return;
358 384
359 gTargetColorSpace = 385 {
360 SkColorSpace::NewICC(profile.data(), profile.size()).release(); 386 sk_sp<SkColorSpace> colorSpace =
387 SkColorSpace::NewICC(profile.data(), profile.size());
388 BitmapImageMetrics::countGamma(colorSpace.get());
389 }
361 390
362 // UMA statistics. 391 // FIXME: Add optional ICCv4 support and support for multiple monitors.
363 BitmapImageMetrics::countGamma(gTargetColorSpace); 392 gTargetColorProfile =
364 #endif // USE(SKCOLORXFORM) 393 qcms_profile_from_memory(profile.data(), profile.size());
394 if (!gTargetColorProfile)
395 return;
396
397 if (qcms_profile_is_bogus(gTargetColorProfile)) {
398 qcms_profile_release(gTargetColorProfile);
399 gTargetColorProfile = nullptr;
400 return;
401 }
402
403 qcms_profile_precache_output_transform(gTargetColorProfile);
404 #endif // USE(QCMSLIB)
365 } 405 }
366 406
367 void ImageDecoder::setColorSpaceAndComputeTransform(const char* iccData, 407 void ImageDecoder::setColorProfileAndComputeTransform(const char* iccData,
368 unsigned iccLength, 408 unsigned iccLength,
369 bool useSRGB) { 409 bool hasAlpha,
410 bool useSRGB) {
370 // Sub-classes should not call this if they were instructed to ignore embedded 411 // Sub-classes should not call this if they were instructed to ignore embedded
371 // color profiles. 412 // color profiles.
372 DCHECK(!m_ignoreGammaAndColorProfile); 413 DCHECK(!m_ignoreGammaAndColorProfile);
373 414
374 m_colorProfile.assign(iccData, iccLength); 415 m_colorProfile.assign(iccData, iccLength);
375 m_hasColorProfile = true; 416 m_hasColorProfile = true;
376 417
377 // With color correct rendering, we do not transform to the output color space 418 // With color correct rendering, we use Skia instead of QCMS to color correct
378 // at decode time. Instead, we tag the raw image pixels and pass the tagged 419 // images.
379 // SkImage to Skia.
380 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) 420 if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
381 return; 421 return;
382 422
383 #if USE(SKCOLORXFORM) 423 #if USE(QCMSLIB)
384 m_sourceToOutputDeviceColorTransform = nullptr; 424 m_sourceToOutputDeviceColorTransform.reset();
385 425
386 // Create the input profile. 426 // Create the input profile
387 sk_sp<SkColorSpace> srcSpace = nullptr; 427 QCMSProfileUniquePtr inputProfile;
388 if (useSRGB) { 428 if (useSRGB) {
389 srcSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); 429 inputProfile.reset(qcms_profile_sRGB());
390 } else { 430 } else {
391 srcSpace = SkColorSpace::NewICC(iccData, iccLength); 431 // Only accept RGB color profiles from input class devices.
432 if (iccLength < kIccColorProfileHeaderLength)
433 return;
434 if (!rgbColorProfile(iccData, iccLength))
435 return;
436 if (!inputDeviceColorProfile(iccData, iccLength))
437 return;
438 inputProfile.reset(qcms_profile_from_memory(iccData, iccLength));
392 } 439 }
440 if (!inputProfile)
441 return;
393 442
394 if (!srcSpace) 443 // We currently only support color profiles for RGB profiled images.
395 return; 444 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile.get()));
396 445
397 // Take a lock around initializing and accessing the global device color 446 // Take a lock around initializing and accessing the global device color
398 // profile. 447 // profile.
399 SpinLock::Guard guard(gTargetColorSpaceLock); 448 SpinLock::Guard guard(gTargetColorProfileLock);
400 449
401 // Initialize the output device profile to sRGB if it has not yet been 450 // Initialize the output device profile to sRGB if it has not yet been
402 // initialized. 451 // initialized.
403 if (!gTargetColorSpace) { 452 if (!gTargetColorProfile) {
404 gTargetColorSpace = 453 gTargetColorProfile = qcms_profile_sRGB();
405 SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).release(); 454 qcms_profile_precache_output_transform(gTargetColorProfile);
406 } 455 }
407 456
408 if (SkColorSpace::Equals(srcSpace.get(), gTargetColorSpace)) { 457 if (qcms_profile_match(inputProfile.get(), gTargetColorProfile))
409 return; 458 return;
410 }
411 459
412 m_sourceToOutputDeviceColorTransform = 460 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8;
413 SkColorSpaceXform::New(srcSpace.get(), gTargetColorSpace); 461
414 #endif // USE(SKCOLORXFORM) 462 // FIXME: Don't force perceptual intent if the image profile contains an
463 // intent.
464 m_sourceToOutputDeviceColorTransform.reset(
465 qcms_transform_create(inputProfile.get(), dataFormat, gTargetColorProfile,
466 QCMS_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL));
467 #endif // USE(QCMSLIB)
415 } 468 }
416 469
417 } // namespace blink 470 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698