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

Side by Side Diff: ui/gfx/icc_profile.cc

Issue 2663153002: Fix id tracking bug in ICCProfile (Closed)
Patch Set: Created 3 years, 10 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 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/icc_profile.h" 5 #include "ui/gfx/icc_profile.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/containers/mru_cache.h" 9 #include "base/containers/mru_cache.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
12 #include "third_party/skia/include/core/SkData.h" 12 #include "third_party/skia/include/core/SkData.h"
13 #include "third_party/skia/include/core/SkICC.h" 13 #include "third_party/skia/include/core/SkICC.h"
14 #include "ui/gfx/color_transform.h" 14 #include "ui/gfx/color_transform.h"
15 15
16 namespace gfx { 16 namespace gfx {
17 17
18 const uint64_t ICCProfile::test_id_adobe_rgb_ = 1;
19 const uint64_t ICCProfile::test_id_color_spin_ = 2;
20 const uint64_t ICCProfile::test_id_generic_rgb_ = 3;
21 const uint64_t ICCProfile::test_id_srgb_ = 4;
22
18 namespace { 23 namespace {
19 const size_t kMinProfileLength = 128; 24 const size_t kMinProfileLength = 128;
20 const size_t kMaxProfileLength = 4 * 1024 * 1024; 25 const size_t kMaxProfileLength = 4 * 1024 * 1024;
21 26
22 // Allow keeping around a maximum of 8 cached ICC profiles. Beware that 27 // Allow keeping around a maximum of 8 cached ICC profiles. Beware that
23 // we will do a linear search thorugh currently-cached ICC profiles, 28 // we will do a linear search thorugh currently-cached ICC profiles,
24 // when creating a new ICC profile. 29 // when creating a new ICC profile.
25 const size_t kMaxCachedICCProfiles = 8; 30 const size_t kMaxCachedICCProfiles = 8;
26 31
27 struct Cache { 32 struct Cache {
28 Cache() : id_to_icc_profile_mru(kMaxCachedICCProfiles) {} 33 Cache() : id_to_icc_profile_mru(kMaxCachedICCProfiles) {}
29 ~Cache() {} 34 ~Cache() {}
30 35
31 // Start from-ICC-data IDs at the end of the hard-coded list. 36 // Start from-ICC-data IDs at the end of the hard-coded test id list above.
32 uint64_t next_unused_id = 5; 37 uint64_t next_unused_id = 5;
33 base::MRUCache<uint64_t, ICCProfile> id_to_icc_profile_mru; 38 base::MRUCache<uint64_t, ICCProfile> id_to_icc_profile_mru;
34 base::Lock lock; 39 base::Lock lock;
35 }; 40 };
36 static base::LazyInstance<Cache> g_cache; 41 static base::LazyInstance<Cache> g_cache;
37 42
38 } // namespace 43 } // namespace
39 44
40 ICCProfile::ICCProfile() = default; 45 ICCProfile::ICCProfile() = default;
41 ICCProfile::ICCProfile(ICCProfile&& other) = default; 46 ICCProfile::ICCProfile(ICCProfile&& other) = default;
42 ICCProfile::ICCProfile(const ICCProfile& other) = default; 47 ICCProfile::ICCProfile(const ICCProfile& other) = default;
43 ICCProfile& ICCProfile::operator=(ICCProfile&& other) = default; 48 ICCProfile& ICCProfile::operator=(ICCProfile&& other) = default;
44 ICCProfile& ICCProfile::operator=(const ICCProfile& other) = default; 49 ICCProfile& ICCProfile::operator=(const ICCProfile& other) = default;
45 ICCProfile::~ICCProfile() = default; 50 ICCProfile::~ICCProfile() = default;
46 51
47 bool ICCProfile::operator==(const ICCProfile& other) const { 52 bool ICCProfile::operator==(const ICCProfile& other) const {
48 return data_ == other.data_; 53 return data_ == other.data_;
49 } 54 }
50 55
51 bool ICCProfile::operator!=(const ICCProfile& other) const { 56 bool ICCProfile::operator!=(const ICCProfile& other) const {
52 return !(*this == other); 57 return !(*this == other);
53 } 58 }
54 59
55 // static 60 // static
56 ICCProfile ICCProfile::FromData(const void* data, size_t size) { 61 ICCProfile ICCProfile::FromData(const void* data, size_t size) {
62 return FromDataWithId(data, size, 0);
63 }
64
65 // static
66 ICCProfile ICCProfile::FromDataWithId(const void* data,
67 size_t size,
68 uint64_t new_profile_id) {
57 if (!IsValidProfileLength(size)) { 69 if (!IsValidProfileLength(size)) {
58 if (size != 0) 70 if (size != 0)
59 DLOG(ERROR) << "Invalid ICC profile length: " << size << "."; 71 DLOG(ERROR) << "Invalid ICC profile length: " << size << ".";
60 return ICCProfile(); 72 return ICCProfile();
61 } 73 }
62 74
63 uint64_t new_profile_id = 0;
64 const char* data_as_char = reinterpret_cast<const char*>(data); 75 const char* data_as_char = reinterpret_cast<const char*>(data);
65 { 76 {
66 // Linearly search the cached ICC profiles to find one with the same data. 77 // Linearly search the cached ICC profiles to find one with the same data.
67 // If it exists, re-use its id and touch it in the cache. 78 // If it exists, re-use its id and touch it in the cache.
68 Cache& cache = g_cache.Get(); 79 Cache& cache = g_cache.Get();
69 base::AutoLock lock(cache.lock); 80 base::AutoLock lock(cache.lock);
70 for (auto iter = cache.id_to_icc_profile_mru.begin(); 81 for (auto iter = cache.id_to_icc_profile_mru.begin();
71 iter != cache.id_to_icc_profile_mru.end(); ++iter) { 82 iter != cache.id_to_icc_profile_mru.end(); ++iter) {
72 const std::vector<char>& iter_data = iter->second.data_; 83 const std::vector<char>& iter_data = iter->second.data_;
73 if (iter_data.size() != size || memcmp(data, iter_data.data(), size)) 84 if (iter_data.size() != size || memcmp(data, iter_data.data(), size))
74 continue; 85 continue;
75 auto found = cache.id_to_icc_profile_mru.Get(iter->second.id_); 86 auto found = cache.id_to_icc_profile_mru.Get(iter->second.id_);
76 return found->second; 87 return found->second;
77 } 88 }
78 new_profile_id = cache.next_unused_id++; 89 if (!new_profile_id)
90 new_profile_id = cache.next_unused_id++;
79 } 91 }
80 92
81 // Create a new cached id and add it to the cache. 93 // Create a new cached id and add it to the cache.
82 ICCProfile icc_profile; 94 ICCProfile icc_profile;
83 icc_profile.id_ = new_profile_id; 95 icc_profile.id_ = new_profile_id;
84 icc_profile.data_.insert(icc_profile.data_.begin(), data_as_char, 96 icc_profile.data_.insert(icc_profile.data_.begin(), data_as_char,
85 data_as_char + size); 97 data_as_char + size);
86 icc_profile.ComputeColorSpaceAndCache(); 98 icc_profile.ComputeColorSpaceAndCache();
87 return icc_profile; 99 return icc_profile;
88 } 100 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 cache.id_to_icc_profile_mru.Put(id_, *this); 253 cache.id_to_icc_profile_mru.Put(id_, *this);
242 } 254 }
243 } 255 }
244 256
245 // static 257 // static
246 bool ICCProfile::IsValidProfileLength(size_t length) { 258 bool ICCProfile::IsValidProfileLength(size_t length) {
247 return length >= kMinProfileLength && length <= kMaxProfileLength; 259 return length >= kMinProfileLength && length <= kMaxProfileLength;
248 } 260 }
249 261
250 } // namespace gfx 262 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698