Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
| 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are | 7 * modification, are permitted provided that the following conditions are |
| 8 * met: | 8 * met: |
| 9 * | 9 * |
| 10 * * Redistributions of source code must retain the above copyright | 10 * * Redistributions of source code must retain the above copyright |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 #include "core/platform/graphics/chromium/Canvas2DLayerBridge.h" | 43 #include "core/platform/graphics/chromium/Canvas2DLayerBridge.h" |
| 44 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" | 44 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" |
| 45 #include "core/platform/graphics/skia/NativeImageSkia.h" | 45 #include "core/platform/graphics/skia/NativeImageSkia.h" |
| 46 #include "core/platform/graphics/skia/SkiaUtils.h" | 46 #include "core/platform/graphics/skia/SkiaUtils.h" |
| 47 #include "core/platform/image-encoders/skia/JPEGImageEncoder.h" | 47 #include "core/platform/image-encoders/skia/JPEGImageEncoder.h" |
| 48 #include "core/platform/image-encoders/skia/PNGImageEncoder.h" | 48 #include "core/platform/image-encoders/skia/PNGImageEncoder.h" |
| 49 #include "core/platform/image-encoders/skia/WEBPImageEncoder.h" | 49 #include "core/platform/image-encoders/skia/WEBPImageEncoder.h" |
| 50 #include "public/platform/Platform.h" | 50 #include "public/platform/Platform.h" |
| 51 #include "skia/ext/platform_canvas.h" | 51 #include "skia/ext/platform_canvas.h" |
| 52 #include "third_party/skia/include/core/SkBitmapDevice.h" | 52 #include "third_party/skia/include/core/SkBitmapDevice.h" |
| 53 #include "third_party/skia/include/core/SkColorFilter.h" | |
| 53 #include "third_party/skia/include/core/SkColorPriv.h" | 54 #include "third_party/skia/include/core/SkColorPriv.h" |
| 54 #include "third_party/skia/include/core/SkSurface.h" | 55 #include "third_party/skia/include/core/SkSurface.h" |
| 56 #include "third_party/skia/include/effects/SkTableColorFilter.h" | |
| 55 #include "third_party/skia/include/gpu/GrContext.h" | 57 #include "third_party/skia/include/gpu/GrContext.h" |
| 56 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 58 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
| 57 #include "wtf/MathExtras.h" | 59 #include "wtf/MathExtras.h" |
| 58 #include "wtf/text/Base64.h" | 60 #include "wtf/text/Base64.h" |
| 59 #include "wtf/text/WTFString.h" | 61 #include "wtf/text/WTFString.h" |
| 60 | 62 |
| 61 using namespace std; | 63 using namespace std; |
| 62 | 64 |
| 63 namespace WebCore { | 65 namespace WebCore { |
| 64 | 66 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, Bl endMode blendMode) | 260 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect, Bl endMode blendMode) |
| 259 { | 261 { |
| 260 if (!isValid()) | 262 if (!isValid()) |
| 261 return; | 263 return; |
| 262 | 264 |
| 263 const SkBitmap& bitmap = *m_context->bitmap(); | 265 const SkBitmap& bitmap = *m_context->bitmap(); |
| 264 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 266 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 265 image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode); | 267 image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode); |
| 266 } | 268 } |
| 267 | 269 |
| 270 static const Vector<uint8_t>& getLinearRgbLUT() | |
| 271 { | |
| 272 DEFINE_STATIC_LOCAL(Vector<uint8_t>, linearRgbLUT, ()); | |
|
pdr.
2013/08/28 03:32:36
Since you know the final size already, can you ini
f(malita)
2013/08/28 19:54:38
Good idea.
Simply passing a constructor size argu
| |
| 273 if (linearRgbLUT.isEmpty()) { | |
| 274 for (unsigned i = 0; i < 256; i++) { | |
| 275 float color = i / 255.0f; | |
| 276 color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) / 1.055f, 2.4f)); | |
| 277 color = std::max(0.0f, color); | |
| 278 color = std::min(1.0f, color); | |
| 279 linearRgbLUT.append(static_cast<uint8_t>(round(color * 255))); | |
| 280 } | |
| 281 } | |
| 282 return linearRgbLUT; | |
| 283 } | |
| 284 | |
| 285 static const Vector<uint8_t>& getDeviceRgbLUT() | |
| 286 { | |
| 287 DEFINE_STATIC_LOCAL(Vector<uint8_t>, deviceRgbLUT, ()); | |
| 288 if (deviceRgbLUT.isEmpty()) { | |
| 289 for (unsigned i = 0; i < 256; i++) { | |
| 290 float color = i / 255.0f; | |
| 291 color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f; | |
| 292 color = std::max(0.0f, color); | |
| 293 color = std::min(1.0f, color); | |
| 294 deviceRgbLUT.append(static_cast<uint8_t>(round(color * 255))); | |
| 295 } | |
| 296 } | |
| 297 return deviceRgbLUT; | |
| 298 } | |
| 299 | |
| 268 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo lorSpace) | 300 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo lorSpace) |
| 269 { | 301 { |
| 270 if (srcColorSpace == dstColorSpace) | 302 if (srcColorSpace == dstColorSpace) |
| 271 return; | 303 return; |
| 272 | 304 |
| 273 // only sRGB <-> linearRGB are supported at the moment | 305 // only sRGB <-> linearRGB are supported at the moment |
| 274 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi ceRGB) | 306 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi ceRGB) |
| 275 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD eviceRGB)) | 307 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD eviceRGB)) |
| 276 return; | 308 return; |
| 277 | 309 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 294 SkColor color = SkPMColorToColor(srcRow[x]); | 326 SkColor color = SkPMColorToColor(srcRow[x]); |
| 295 srcRow[x] = SkPreMultiplyARGB( | 327 srcRow[x] = SkPreMultiplyARGB( |
| 296 SkColorGetA(color), | 328 SkColorGetA(color), |
| 297 lookUpTable[SkColorGetR(color)], | 329 lookUpTable[SkColorGetR(color)], |
| 298 lookUpTable[SkColorGetG(color)], | 330 lookUpTable[SkColorGetG(color)], |
| 299 lookUpTable[SkColorGetB(color)]); | 331 lookUpTable[SkColorGetB(color)]); |
| 300 } | 332 } |
| 301 } | 333 } |
| 302 } | 334 } |
| 303 | 335 |
| 304 const Vector<uint8_t>& ImageBuffer::getLinearRgbLUT() | 336 PassRefPtr<SkColorFilter> ImageBuffer::createColorSpaceFilter(ColorSpace srcColo rSpace, |
|
Stephen White
2013/08/28 14:11:10
Maybe at some point we can use this in place of Im
f(malita)
2013/08/28 19:54:38
Makes sense. The only transformColorSpace() user l
| |
| 337 ColorSpace dstColorSpace) | |
| 305 { | 338 { |
| 306 DEFINE_STATIC_LOCAL(Vector<uint8_t>, linearRgbLUT, ()); | 339 if ((srcColorSpace == dstColorSpace) |
| 307 if (linearRgbLUT.isEmpty()) { | 340 || (srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceD eviceRGB) |
| 308 for (unsigned i = 0; i < 256; i++) { | 341 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD eviceRGB)) |
| 309 float color = i / 255.0f; | 342 return 0; |
| 310 color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) / 1.055f, 2.4f)); | 343 |
| 311 color = std::max(0.0f, color); | 344 const uint8_t* lut = 0; |
| 312 color = std::min(1.0f, color); | 345 if (dstColorSpace == ColorSpaceLinearRGB) |
| 313 linearRgbLUT.append(static_cast<uint8_t>(round(color * 255))); | 346 lut = &getLinearRgbLUT()[0]; |
| 314 } | 347 else if (dstColorSpace == ColorSpaceDeviceRGB) |
| 315 } | 348 lut = &getDeviceRgbLUT()[0]; |
| 316 return linearRgbLUT; | 349 else |
| 350 return 0; | |
| 351 | |
| 352 return adoptRef(SkTableColorFilter::CreateARGB(0, lut, lut, lut)); | |
| 317 } | 353 } |
| 318 | 354 |
| 319 const Vector<uint8_t>& ImageBuffer::getDeviceRgbLUT() | |
| 320 { | |
| 321 DEFINE_STATIC_LOCAL(Vector<uint8_t>, deviceRgbLUT, ()); | |
| 322 if (deviceRgbLUT.isEmpty()) { | |
| 323 for (unsigned i = 0; i < 256; i++) { | |
| 324 float color = i / 255.0f; | |
| 325 color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f; | |
| 326 color = std::max(0.0f, color); | |
| 327 color = std::min(1.0f, color); | |
| 328 deviceRgbLUT.append(static_cast<uint8_t>(round(color * 255))); | |
| 329 } | |
| 330 } | |
| 331 return deviceRgbLUT; | |
| 332 } | |
| 333 | |
| 334 | |
| 335 template <Multiply multiplied> | 355 template <Multiply multiplied> |
| 336 PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, GraphicsContext* context, const IntSize& size) | 356 PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, GraphicsContext* context, const IntSize& size) |
| 337 { | 357 { |
| 338 float area = 4.0f * rect.width() * rect.height(); | 358 float area = 4.0f * rect.width() * rect.height(); |
| 339 if (area > static_cast<float>(std::numeric_limits<int>::max())) | 359 if (area > static_cast<float>(std::numeric_limits<int>::max())) |
| 340 return 0; | 360 return 0; |
| 341 | 361 |
| 342 RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(re ct.width() * rect.height() * 4); | 362 RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(re ct.width() * rect.height() * 4); |
| 343 | 363 |
| 344 unsigned char* data = result->data(); | 364 unsigned char* data = result->data(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 | 436 |
| 417 SkCanvas::Config8888 config8888; | 437 SkCanvas::Config8888 config8888; |
| 418 if (multiplied == Premultiplied) | 438 if (multiplied == Premultiplied) |
| 419 config8888 = SkCanvas::kRGBA_Premul_Config8888; | 439 config8888 = SkCanvas::kRGBA_Premul_Config8888; |
| 420 else | 440 else |
| 421 config8888 = SkCanvas::kRGBA_Unpremul_Config8888; | 441 config8888 = SkCanvas::kRGBA_Unpremul_Config8888; |
| 422 | 442 |
| 423 context()->writePixels(srcBitmap, destX, destY, config8888); | 443 context()->writePixels(srcBitmap, destX, destY, config8888); |
| 424 } | 444 } |
| 425 | 445 |
| 426 void ImageBuffer::convertToLuminanceMask() | |
| 427 { | |
| 428 IntRect luminanceRect(IntPoint(), internalSize()); | |
| 429 RefPtr<Uint8ClampedArray> srcPixelArray = getUnmultipliedImageData(luminance Rect); | |
| 430 | |
| 431 unsigned pixelArrayLength = srcPixelArray->length(); | |
| 432 for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset + = 4) { | |
| 433 unsigned char a = srcPixelArray->item(pixelOffset + 3); | |
| 434 if (!a) | |
| 435 continue; | |
| 436 unsigned char r = srcPixelArray->item(pixelOffset); | |
| 437 unsigned char g = srcPixelArray->item(pixelOffset + 1); | |
| 438 unsigned char b = srcPixelArray->item(pixelOffset + 2); | |
| 439 | |
| 440 double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255. 0); | |
| 441 srcPixelArray->set(pixelOffset + 3, luma); | |
| 442 } | |
| 443 putByteArray(Unmultiplied, srcPixelArray.get(), luminanceRect.size(), lumina nceRect, IntPoint()); | |
| 444 } | |
| 445 | |
| 446 template <typename T> | 446 template <typename T> |
| 447 static bool encodeImage(T& source, const String& mimeType, const double* quality , Vector<char>* output) | 447 static bool encodeImage(T& source, const String& mimeType, const double* quality , Vector<char>* output) |
| 448 { | 448 { |
| 449 Vector<unsigned char>* encodedImage = reinterpret_cast<Vector<unsigned char> *>(output); | 449 Vector<unsigned char>* encodedImage = reinterpret_cast<Vector<unsigned char> *>(output); |
| 450 | 450 |
| 451 if (mimeType == "image/jpeg") { | 451 if (mimeType == "image/jpeg") { |
| 452 int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; | 452 int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; |
| 453 if (quality && *quality >= 0.0 && *quality <= 1.0) | 453 if (quality && *quality >= 0.0 && *quality <= 1.0) |
| 454 compressionQuality = static_cast<int>(*quality * 100 + 0.5); | 454 compressionQuality = static_cast<int>(*quality * 100 + 0.5); |
| 455 if (!JPEGImageEncoder::encode(source, compressionQuality, encodedImage)) | 455 if (!JPEGImageEncoder::encode(source, compressionQuality, encodedImage)) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) | 490 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) |
| 491 return "data:,"; | 491 return "data:,"; |
| 492 | 492 |
| 493 Vector<char> base64Data; | 493 Vector<char> base64Data; |
| 494 base64Encode(encodedImage, base64Data); | 494 base64Encode(encodedImage, base64Data); |
| 495 | 495 |
| 496 return "data:" + mimeType + ";base64," + base64Data; | 496 return "data:" + mimeType + ";base64," + base64Data; |
| 497 } | 497 } |
| 498 | 498 |
| 499 } // namespace WebCore | 499 } // namespace WebCore |
| OLD | NEW |