| 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, ()); |
| 273 if (linearRgbLUT.isEmpty()) { |
| 274 linearRgbLUT.reserveCapacity(256); |
| 275 for (unsigned i = 0; i < 256; i++) { |
| 276 float color = i / 255.0f; |
| 277 color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) /
1.055f, 2.4f)); |
| 278 color = std::max(0.0f, color); |
| 279 color = std::min(1.0f, color); |
| 280 linearRgbLUT.append(static_cast<uint8_t>(round(color * 255))); |
| 281 } |
| 282 } |
| 283 return linearRgbLUT; |
| 284 } |
| 285 |
| 286 static const Vector<uint8_t>& getDeviceRgbLUT() |
| 287 { |
| 288 DEFINE_STATIC_LOCAL(Vector<uint8_t>, deviceRgbLUT, ()); |
| 289 if (deviceRgbLUT.isEmpty()) { |
| 290 deviceRgbLUT.reserveCapacity(256); |
| 291 for (unsigned i = 0; i < 256; i++) { |
| 292 float color = i / 255.0f; |
| 293 color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f; |
| 294 color = std::max(0.0f, color); |
| 295 color = std::min(1.0f, color); |
| 296 deviceRgbLUT.append(static_cast<uint8_t>(round(color * 255))); |
| 297 } |
| 298 } |
| 299 return deviceRgbLUT; |
| 300 } |
| 301 |
| 268 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
lorSpace) | 302 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
lorSpace) |
| 269 { | 303 { |
| 270 if (srcColorSpace == dstColorSpace) | 304 if (srcColorSpace == dstColorSpace) |
| 271 return; | 305 return; |
| 272 | 306 |
| 273 // only sRGB <-> linearRGB are supported at the moment | 307 // only sRGB <-> linearRGB are supported at the moment |
| 274 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi
ceRGB) | 308 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi
ceRGB) |
| 275 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD
eviceRGB)) | 309 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD
eviceRGB)) |
| 276 return; | 310 return; |
| 277 | 311 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 294 SkColor color = SkPMColorToColor(srcRow[x]); | 328 SkColor color = SkPMColorToColor(srcRow[x]); |
| 295 srcRow[x] = SkPreMultiplyARGB( | 329 srcRow[x] = SkPreMultiplyARGB( |
| 296 SkColorGetA(color), | 330 SkColorGetA(color), |
| 297 lookUpTable[SkColorGetR(color)], | 331 lookUpTable[SkColorGetR(color)], |
| 298 lookUpTable[SkColorGetG(color)], | 332 lookUpTable[SkColorGetG(color)], |
| 299 lookUpTable[SkColorGetB(color)]); | 333 lookUpTable[SkColorGetB(color)]); |
| 300 } | 334 } |
| 301 } | 335 } |
| 302 } | 336 } |
| 303 | 337 |
| 304 const Vector<uint8_t>& ImageBuffer::getLinearRgbLUT() | 338 PassRefPtr<SkColorFilter> ImageBuffer::createColorSpaceFilter(ColorSpace srcColo
rSpace, |
| 339 ColorSpace dstColorSpace) |
| 305 { | 340 { |
| 306 DEFINE_STATIC_LOCAL(Vector<uint8_t>, linearRgbLUT, ()); | 341 if ((srcColorSpace == dstColorSpace) |
| 307 if (linearRgbLUT.isEmpty()) { | 342 || (srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceD
eviceRGB) |
| 308 for (unsigned i = 0; i < 256; i++) { | 343 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD
eviceRGB)) |
| 309 float color = i / 255.0f; | 344 return 0; |
| 310 color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) /
1.055f, 2.4f)); | 345 |
| 311 color = std::max(0.0f, color); | 346 const uint8_t* lut = 0; |
| 312 color = std::min(1.0f, color); | 347 if (dstColorSpace == ColorSpaceLinearRGB) |
| 313 linearRgbLUT.append(static_cast<uint8_t>(round(color * 255))); | 348 lut = &getLinearRgbLUT()[0]; |
| 314 } | 349 else if (dstColorSpace == ColorSpaceDeviceRGB) |
| 315 } | 350 lut = &getDeviceRgbLUT()[0]; |
| 316 return linearRgbLUT; | 351 else |
| 352 return 0; |
| 353 |
| 354 return adoptRef(SkTableColorFilter::CreateARGB(0, lut, lut, lut)); |
| 317 } | 355 } |
| 318 | 356 |
| 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> | 357 template <Multiply multiplied> |
| 336 PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, GraphicsContext*
context, const IntSize& size) | 358 PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, GraphicsContext*
context, const IntSize& size) |
| 337 { | 359 { |
| 338 float area = 4.0f * rect.width() * rect.height(); | 360 float area = 4.0f * rect.width() * rect.height(); |
| 339 if (area > static_cast<float>(std::numeric_limits<int>::max())) | 361 if (area > static_cast<float>(std::numeric_limits<int>::max())) |
| 340 return 0; | 362 return 0; |
| 341 | 363 |
| 342 RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(re
ct.width() * rect.height() * 4); | 364 RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(re
ct.width() * rect.height() * 4); |
| 343 | 365 |
| 344 unsigned char* data = result->data(); | 366 unsigned char* data = result->data(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 438 |
| 417 SkCanvas::Config8888 config8888; | 439 SkCanvas::Config8888 config8888; |
| 418 if (multiplied == Premultiplied) | 440 if (multiplied == Premultiplied) |
| 419 config8888 = SkCanvas::kRGBA_Premul_Config8888; | 441 config8888 = SkCanvas::kRGBA_Premul_Config8888; |
| 420 else | 442 else |
| 421 config8888 = SkCanvas::kRGBA_Unpremul_Config8888; | 443 config8888 = SkCanvas::kRGBA_Unpremul_Config8888; |
| 422 | 444 |
| 423 context()->writePixels(srcBitmap, destX, destY, config8888); | 445 context()->writePixels(srcBitmap, destX, destY, config8888); |
| 424 } | 446 } |
| 425 | 447 |
| 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> | 448 template <typename T> |
| 447 static bool encodeImage(T& source, const String& mimeType, const double* quality
, Vector<char>* output) | 449 static bool encodeImage(T& source, const String& mimeType, const double* quality
, Vector<char>* output) |
| 448 { | 450 { |
| 449 Vector<unsigned char>* encodedImage = reinterpret_cast<Vector<unsigned char>
*>(output); | 451 Vector<unsigned char>* encodedImage = reinterpret_cast<Vector<unsigned char>
*>(output); |
| 450 | 452 |
| 451 if (mimeType == "image/jpeg") { | 453 if (mimeType == "image/jpeg") { |
| 452 int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; | 454 int compressionQuality = JPEGImageEncoder::DefaultCompressionQuality; |
| 453 if (quality && *quality >= 0.0 && *quality <= 1.0) | 455 if (quality && *quality >= 0.0 && *quality <= 1.0) |
| 454 compressionQuality = static_cast<int>(*quality * 100 + 0.5); | 456 compressionQuality = static_cast<int>(*quality * 100 + 0.5); |
| 455 if (!JPEGImageEncoder::encode(source, compressionQuality, encodedImage)) | 457 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)) | 492 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) |
| 491 return "data:,"; | 493 return "data:,"; |
| 492 | 494 |
| 493 Vector<char> base64Data; | 495 Vector<char> base64Data; |
| 494 base64Encode(encodedImage, base64Data); | 496 base64Encode(encodedImage, base64Data); |
| 495 | 497 |
| 496 return "data:" + mimeType + ";base64," + base64Data; | 498 return "data:" + mimeType + ";base64," + base64Data; |
| 497 } | 499 } |
| 498 | 500 |
| 499 } // namespace WebCore | 501 } // namespace WebCore |
| OLD | NEW |