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

Side by Side Diff: third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp

Issue 2575693005: Add unit test for color managed ImageBitamp(ImageBitmap) constructor (Closed)
Patch Set: Addressing comments Created 3 years, 12 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013, Google Inc. All rights reserved. 2 * Copyright (c) 2013, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * 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 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 15 matching lines...) Expand all
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "core/frame/ImageBitmap.h" 31 #include "core/frame/ImageBitmap.h"
32 32
33 #include "SkPixelRef.h" // FIXME: qualify this skia header file. 33 #include "SkPixelRef.h" // FIXME: qualify this skia header file.
34 #include "core/dom/Document.h" 34 #include "core/dom/Document.h"
35 #include "core/fetch/MemoryCache.h" 35 #include "core/fetch/MemoryCache.h"
36 #include "core/frame/FrameView.h"
36 #include "core/html/HTMLCanvasElement.h" 37 #include "core/html/HTMLCanvasElement.h"
37 #include "core/html/HTMLImageElement.h" 38 #include "core/html/HTMLImageElement.h"
38 #include "core/html/HTMLVideoElement.h" 39 #include "core/html/HTMLVideoElement.h"
39 #include "core/loader/resource/ImageResourceContent.h" 40 #include "core/loader/resource/ImageResourceContent.h"
40 #include "platform/graphics/StaticBitmapImage.h" 41 #include "platform/graphics/StaticBitmapImage.h"
41 #include "platform/graphics/skia/SkiaUtils.h" 42 #include "platform/graphics/skia/SkiaUtils.h"
42 #include "platform/heap/Handle.h" 43 #include "platform/heap/Handle.h"
43 #include "platform/image-decoders/ImageDecoder.h" 44 #include "platform/image-decoders/ImageDecoder.h"
44 #include "platform/network/ResourceRequest.h" 45 #include "platform/network/ResourceRequest.h"
45 #include "testing/gtest/include/gtest/gtest.h" 46 #include "testing/gtest/include/gtest/gtest.h"
(...skipping 12 matching lines...) Expand all
58 m_image = surface->makeImageSnapshot(); 59 m_image = surface->makeImageSnapshot();
59 60
60 sk_sp<SkSurface> surface2 = SkSurface::MakeRasterN32Premul(5, 5); 61 sk_sp<SkSurface> surface2 = SkSurface::MakeRasterN32Premul(5, 5);
61 surface2->getCanvas()->clear(0xAAAAAAAA); 62 surface2->getCanvas()->clear(0xAAAAAAAA);
62 m_image2 = surface2->makeImageSnapshot(); 63 m_image2 = surface2->makeImageSnapshot();
63 64
64 // Save the global memory cache to restore it upon teardown. 65 // Save the global memory cache to restore it upon teardown.
65 m_globalMemoryCache = replaceMemoryCacheForTesting(MemoryCache::create()); 66 m_globalMemoryCache = replaceMemoryCacheForTesting(MemoryCache::create());
66 67
67 // Save the state of experimental canvas features and color correct 68 // Save the state of experimental canvas features and color correct
68 // rendering flags to restore them on teardown. 69 // rendering flags to restore them on teardown. Each test that changes the
70 // flags must restore them to prevent affecting other ImageBitmap tests.
71 // This is an extra safety precaution to prevent such an error to leak from
72 // this test suite.
dcheng 2016/12/19 21:01:03 Nit: probably revert the latter half of the commen
69 experimentalCanvasFeatures = 73 experimentalCanvasFeatures =
70 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); 74 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
71 colorCorrectRendering = 75 colorCorrectRendering =
72 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); 76 RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
73 colorCorrectRenderingDefaultMode = 77 colorCorrectRenderingDefaultMode =
74 RuntimeEnabledFeatures::colorCorrectRenderingDefaultModeEnabled(); 78 RuntimeEnabledFeatures::colorCorrectRenderingDefaultModeEnabled();
75 } 79 }
76 virtual void TearDown() { 80 virtual void TearDown() {
77 // Garbage collection is required prior to switching out the 81 // Garbage collection is required prior to switching out the
78 // test's memory cache; image resources are released, evicting 82 // test's memory cache; image resources are released, evicting
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 enum class ColorSpaceConversion : uint8_t { 211 enum class ColorSpaceConversion : uint8_t {
208 NONE = 0, 212 NONE = 0,
209 DEFAULT_NOT_COLOR_CORRECTED = 1, 213 DEFAULT_NOT_COLOR_CORRECTED = 1,
210 DEFAULT_COLOR_CORRECTED = 2, 214 DEFAULT_COLOR_CORRECTED = 2,
211 SRGB = 3, 215 SRGB = 3,
212 LINEAR_RGB = 4, 216 LINEAR_RGB = 4,
213 217
214 LAST = LINEAR_RGB 218 LAST = LINEAR_RGB
215 }; 219 };
216 220
217 static ImageBitmap* createImageBitmapWithColorSpaceConversion( 221 static ImageBitmapOptions prepareBitmapOptionsAndSetRuntimeFlags(
218 HTMLImageElement* image,
219 Optional<IntRect>& cropRect,
220 Document* document,
221 const ColorSpaceConversion& colorSpaceConversion) { 222 const ColorSpaceConversion& colorSpaceConversion) {
222 // Set the color space conversion in ImageBitmapOptions 223 // Set the color space conversion in ImageBitmapOptions
223 ImageBitmapOptions options; 224 ImageBitmapOptions options;
224 static const Vector<String> conversions = {"none", "default", "default", 225 static const Vector<String> conversions = {"none", "default", "default",
225 "srgb", "linear-rgb"}; 226 "srgb", "linear-rgb"};
226 options.setColorSpaceConversion( 227 options.setColorSpaceConversion(
227 conversions[static_cast<uint8_t>(colorSpaceConversion)]); 228 conversions[static_cast<uint8_t>(colorSpaceConversion)]);
228 229
229 // Set the runtime flags 230 // Set the runtime flags
230 bool flag = (colorSpaceConversion != 231 bool flag = (colorSpaceConversion !=
231 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); 232 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED);
232 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); 233 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true);
233 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(flag); 234 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(flag);
234 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled(!flag); 235 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled(!flag);
235 236
236 // Create and return the ImageBitmap 237 return options;
237 return ImageBitmap::create(image, cropRect, &(image->document()), options);
238 } 238 }
239 239
240 TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversion) { 240 TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
241 HTMLImageElement* imageElement = 241 HTMLImageElement* imageElement =
242 HTMLImageElement::create(*Document::create()); 242 HTMLImageElement::create(*Document::create());
243 243
244 SkPaint p; 244 SkPaint p;
245 p.setColor(SK_ColorRED); 245 p.setColor(SK_ColorRED);
246 sk_sp<SkColorSpace> srcRGBColorSpace = 246 sk_sp<SkColorSpace> srcRGBColorSpace =
247 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); 247 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
248 248
249 SkImageInfo rasterImageInfo = 249 SkImageInfo rasterImageInfo =
250 SkImageInfo::MakeN32Premul(100, 100, srcRGBColorSpace); 250 SkImageInfo::MakeN32Premul(10, 10, srcRGBColorSpace);
251 sk_sp<SkSurface> surface(SkSurface::MakeRaster(rasterImageInfo)); 251 sk_sp<SkSurface> surface(SkSurface::MakeRaster(rasterImageInfo));
252 surface->getCanvas()->drawCircle(50, 50, 50, p); 252 surface->getCanvas()->drawCircle(5, 5, 5, p);
253 sk_sp<SkImage> image = surface->makeImageSnapshot(); 253 sk_sp<SkImage> image = surface->makeImageSnapshot();
254 254
255 std::unique_ptr<uint8_t[]> srcPixel( 255 std::unique_ptr<uint8_t[]> srcPixel(
256 new uint8_t[rasterImageInfo.bytesPerPixel()]()); 256 new uint8_t[rasterImageInfo.bytesPerPixel()]());
257 image->readPixels(rasterImageInfo.makeWH(1, 1), srcPixel.get(), 257 image->readPixels(rasterImageInfo.makeWH(1, 1), srcPixel.get(),
258 image->width() * rasterImageInfo.bytesPerPixel(), 50, 50); 258 image->width() * rasterImageInfo.bytesPerPixel(), 5, 5);
259 259
260 ImageResourceContent* originalImageResource = 260 ImageResourceContent* originalImageResource =
261 ImageResourceContent::create(StaticBitmapImage::create(image).get()); 261 ImageResourceContent::create(StaticBitmapImage::create(image).get());
262 imageElement->setImageResource(originalImageResource); 262 imageElement->setImageResource(originalImageResource);
263 263
264 Optional<IntRect> cropRect = IntRect(0, 0, image->width(), image->height()); 264 Optional<IntRect> cropRect = IntRect(0, 0, image->width(), image->height());
265 265
266 // Create and test the ImageBitmap objects. 266 // Create and test the ImageBitmap objects.
267 // We don't check "none" color space conversion as it requires the encoded 267 // We don't check "none" color space conversion as it requires the encoded
268 // data in a format readable by ImageDecoder. Furthermore, the code path for 268 // data in a format readable by ImageDecoder. Furthermore, the code path for
269 // "none" color space conversion is not affected by this CL. 269 // "none" color space conversion is not affected by this CL.
270 270
271 sk_sp<SkColorSpace> colorSpace = nullptr; 271 sk_sp<SkColorSpace> colorSpace = nullptr;
272 SkColorType colorType = SkColorType::kN32_SkColorType; 272 SkColorType colorType = SkColorType::kN32_SkColorType;
273 SkColorSpaceXform::ColorFormat colorFormat32 = 273 SkColorSpaceXform::ColorFormat colorFormat32 =
274 (colorType == kBGRA_8888_SkColorType) 274 (colorType == kBGRA_8888_SkColorType)
275 ? SkColorSpaceXform::ColorFormat::kBGRA_8888_ColorFormat 275 ? SkColorSpaceXform::ColorFormat::kBGRA_8888_ColorFormat
276 : SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; 276 : SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
277 SkColorSpaceXform::ColorFormat colorFormat = colorFormat32; 277 SkColorSpaceXform::ColorFormat colorFormat = colorFormat32;
278 278
279 for (uint8_t i = static_cast<uint8_t>( 279 for (uint8_t i = static_cast<uint8_t>(
280 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); 280 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED);
281 i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) { 281 i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
282 ColorSpaceConversion colorSpaceConversion = 282 ColorSpaceConversion colorSpaceConversion =
283 static_cast<ColorSpaceConversion>(i); 283 static_cast<ColorSpaceConversion>(i);
284 ImageBitmap* imageBitmap = createImageBitmapWithColorSpaceConversion( 284 ImageBitmapOptions options =
285 imageElement, cropRect, &(imageElement->document()), 285 prepareBitmapOptionsAndSetRuntimeFlags(colorSpaceConversion);
286 colorSpaceConversion); 286 ImageBitmap* imageBitmap = ImageBitmap::create(
287 imageElement, cropRect, &(imageElement->document()), options);
288
289 // ColorBehavior::ignore() is used instead of
290 // ColorBehavior::transformToTargetForTesting() to avoid color conversion to
291 // display color profile, as we want to solely rely on the color correction
292 // that happens in ImageBitmap create method.
287 SkImage* convertedImage = 293 SkImage* convertedImage =
288 imageBitmap->bitmapImage() 294 imageBitmap->bitmapImage()
289 ->imageForCurrentFrame(ColorBehavior::ignore()) 295 ->imageForCurrentFrame(ColorBehavior::ignore())
290 .get(); 296 .get();
291 297
292 switch (colorSpaceConversion) { 298 switch (colorSpaceConversion) {
293 case ColorSpaceConversion::NONE: 299 case ColorSpaceConversion::NONE:
294 NOTREACHED(); 300 NOTREACHED();
295 break; 301 break;
296 case ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED: 302 case ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED:
(...skipping 16 matching lines...) Expand all
313 default: 319 default:
314 NOTREACHED(); 320 NOTREACHED();
315 } 321 }
316 322
317 SkImageInfo imageInfo = SkImageInfo::Make( 323 SkImageInfo imageInfo = SkImageInfo::Make(
318 1, 1, colorType, SkAlphaType::kPremul_SkAlphaType, colorSpace); 324 1, 1, colorType, SkAlphaType::kPremul_SkAlphaType, colorSpace);
319 std::unique_ptr<uint8_t[]> convertedPixel( 325 std::unique_ptr<uint8_t[]> convertedPixel(
320 new uint8_t[imageInfo.bytesPerPixel()]()); 326 new uint8_t[imageInfo.bytesPerPixel()]());
321 convertedImage->readPixels( 327 convertedImage->readPixels(
322 imageInfo, convertedPixel.get(), 328 imageInfo, convertedPixel.get(),
323 convertedImage->width() * imageInfo.bytesPerPixel(), 50, 50); 329 convertedImage->width() * imageInfo.bytesPerPixel(), 5, 5);
324 330
325 // Transform the source pixel and check if the image bitmap color conversion 331 // Transform the source pixel and check if the image bitmap color conversion
326 // is done correctly. 332 // is done correctly.
333 std::unique_ptr<SkColorSpaceXform> colorSpaceXform =
334 SkColorSpaceXform::New(srcRGBColorSpace.get(), colorSpace.get());
335 std::unique_ptr<uint8_t[]> transformedPixel(
336 new uint8_t[imageInfo.bytesPerPixel()]());
337 colorSpaceXform->apply(colorFormat, transformedPixel.get(), colorFormat32,
338 srcPixel.get(), 1, SkAlphaType::kPremul_SkAlphaType);
339
340 int compare = std::memcmp(convertedPixel.get(), transformedPixel.get(),
341 imageInfo.bytesPerPixel());
342 ASSERT_EQ(compare, 0);
343 }
344 }
345
346 TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
347 HTMLImageElement* imageElement =
348 HTMLImageElement::create(*Document::create());
349
350 SkPaint p;
351 p.setColor(SK_ColorRED);
352 sk_sp<SkColorSpace> srcRGBColorSpace =
353 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
354
355 SkImageInfo rasterImageInfo =
356 SkImageInfo::MakeN32Premul(10, 10, srcRGBColorSpace);
357 sk_sp<SkSurface> surface(SkSurface::MakeRaster(rasterImageInfo));
358 surface->getCanvas()->drawCircle(5, 5, 5, p);
359 sk_sp<SkImage> image = surface->makeImageSnapshot();
360
361 std::unique_ptr<uint8_t[]> srcPixel(
362 new uint8_t[rasterImageInfo.bytesPerPixel()]());
363 image->readPixels(rasterImageInfo.makeWH(1, 1), srcPixel.get(),
364 image->width() * rasterImageInfo.bytesPerPixel(), 5, 5);
365
366 ImageResourceContent* sourceImageResource =
367 ImageResourceContent::create(StaticBitmapImage::create(image).get());
368 imageElement->setImageResource(sourceImageResource);
369
370 Optional<IntRect> cropRect = IntRect(0, 0, image->width(), image->height());
371 ImageBitmapOptions options =
372 prepareBitmapOptionsAndSetRuntimeFlags(ColorSpaceConversion::SRGB);
373 ImageBitmap* sourceImageBitmap = ImageBitmap::create(
374 imageElement, cropRect, &(imageElement->document()), options);
375
376 sk_sp<SkColorSpace> colorSpace = nullptr;
377 SkColorType colorType = SkColorType::kN32_SkColorType;
378 SkColorSpaceXform::ColorFormat colorFormat32 =
379 (colorType == kBGRA_8888_SkColorType)
380 ? SkColorSpaceXform::ColorFormat::kBGRA_8888_ColorFormat
381 : SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
382 SkColorSpaceXform::ColorFormat colorFormat = colorFormat32;
383
384 for (uint8_t i = static_cast<uint8_t>(
385 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED);
386 i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
387 ColorSpaceConversion colorSpaceConversion =
388 static_cast<ColorSpaceConversion>(i);
389 options = prepareBitmapOptionsAndSetRuntimeFlags(colorSpaceConversion);
390 ImageBitmap* imageBitmap =
391 ImageBitmap::create(sourceImageBitmap, cropRect, options);
392 // ColorBehavior::ignore() is used instead of
393 // ColorBehavior::transformToTargetForTesting() to avoid color conversion to
394 // display color profile, as we want to solely rely on the color correction
395 // that happens in ImageBitmap create method.
396 SkImage* convertedImage =
397 imageBitmap->bitmapImage()
398 ->imageForCurrentFrame(ColorBehavior::ignore())
399 .get();
400
401 switch (colorSpaceConversion) {
402 case ColorSpaceConversion::NONE:
403 NOTREACHED();
404 break;
405 case ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED:
406 // TODO(zakerinasab): Replace sRGB with a call to
407 // ImageDecoder::globalTargetColorSpace() when the crash problem on Mac
408 // is fixed. crbug.com/668546.
409 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
410 colorFormat = colorFormat32;
411 break;
412 case ColorSpaceConversion::DEFAULT_COLOR_CORRECTED:
413 case ColorSpaceConversion::SRGB:
414 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
415 colorFormat = colorFormat32;
416 break;
417 case ColorSpaceConversion::LINEAR_RGB:
418 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named);
419 colorType = SkColorType::kRGBA_F16_SkColorType;
420 colorFormat = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
421 break;
422 default:
423 NOTREACHED();
424 }
425
426 SkImageInfo imageInfo = SkImageInfo::Make(
427 1, 1, colorType, SkAlphaType::kPremul_SkAlphaType, colorSpace);
428 std::unique_ptr<uint8_t[]> convertedPixel(
429 new uint8_t[imageInfo.bytesPerPixel()]());
430 convertedImage->readPixels(
431 imageInfo, convertedPixel.get(),
432 convertedImage->width() * imageInfo.bytesPerPixel(), 5, 5);
433
434 // Transform the source pixel and check if the image bitmap color conversion
435 // is done correctly.
327 std::unique_ptr<SkColorSpaceXform> colorSpaceXform = 436 std::unique_ptr<SkColorSpaceXform> colorSpaceXform =
328 SkColorSpaceXform::New(srcRGBColorSpace.get(), colorSpace.get()); 437 SkColorSpaceXform::New(srcRGBColorSpace.get(), colorSpace.get());
329 std::unique_ptr<uint8_t[]> transformedPixel( 438 std::unique_ptr<uint8_t[]> transformedPixel(
330 new uint8_t[imageInfo.bytesPerPixel()]()); 439 new uint8_t[imageInfo.bytesPerPixel()]());
331 colorSpaceXform->apply(colorFormat, transformedPixel.get(), colorFormat32, 440 colorSpaceXform->apply(colorFormat, transformedPixel.get(), colorFormat32,
332 srcPixel.get(), 1, SkAlphaType::kPremul_SkAlphaType); 441 srcPixel.get(), 1, SkAlphaType::kPremul_SkAlphaType);
333 442
334 int compare = std::memcmp(convertedPixel.get(), transformedPixel.get(), 443 int compare = std::memcmp(convertedPixel.get(), transformedPixel.get(),
335 imageInfo.bytesPerPixel()); 444 imageInfo.bytesPerPixel());
336 ASSERT_EQ(compare, 0); 445 ASSERT_EQ(compare, 0);
337 } 446 }
338 } 447 }
339 448
340 } // namespace blink 449 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698