OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. |
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
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 | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 | 480 |
481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). | 481 // FIXME: Make isSupportedImageMIMETypeForEncoding threadsafe (to allow this
method to be used on a worker thread). |
482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) | 482 if (mimeType.isNull() || !MIMETypeRegistry::isSupportedImageMIMETypeForEncod
ing(lowercaseMimeType)) |
483 lowercaseMimeType = "image/png"; | 483 lowercaseMimeType = "image/png"; |
484 | 484 |
485 return lowercaseMimeType; | 485 return lowercaseMimeType; |
486 } | 486 } |
487 | 487 |
488 const AtomicString HTMLCanvasElement::imageSourceURL() const | 488 const AtomicString HTMLCanvasElement::imageSourceURL() const |
489 { | 489 { |
490 return AtomicString(toDataURLInternal("image/png", 0, FrontBuffer)); | 490 NonThrowableExceptionState exceptionState; |
| 491 AtomicString dataURL(toDataURLInternal("image/png", 0, FrontBuffer, exceptio
nState)); |
| 492 if (exceptionState.hadException()) |
| 493 return AtomicString("data:,"); |
| 494 return dataURL; |
491 } | 495 } |
492 | 496 |
493 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const | 497 void HTMLCanvasElement::prepareSurfaceForPaintingIfNeeded() const |
494 { | 498 { |
495 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context | 499 ASSERT(m_context && m_context->is2d()); // This function is called by the 2d
context |
496 if (buffer()) | 500 if (buffer()) |
497 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); | 501 m_imageBuffer->prepareSurfaceForPaintingIfNeeded(); |
498 } | 502 } |
499 | 503 |
500 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer) cons
t | 504 ImageData* HTMLCanvasElement::toImageData(SourceDrawingBuffer sourceBuffer, Exce
ptionState& exceptionState) const |
501 { | 505 { |
502 ImageData* imageData; | 506 ImageData* imageData; |
503 if (is3D()) { | 507 if (is3D()) { |
504 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). | 508 // Get non-premultiplied data because of inaccurate premultiplied alpha
conversion of buffer()->toDataURL(). |
505 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); | 509 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); |
506 if (imageData) | 510 if (imageData) |
507 return imageData; | 511 return imageData; |
508 | 512 |
509 m_context->paintRenderingResultsToCanvas(sourceBuffer); | 513 m_context->paintRenderingResultsToCanvas(sourceBuffer); |
510 imageData = ImageData::create(m_size); | 514 imageData = ImageData::create(m_size, exceptionState); |
| 515 if (exceptionState.hadException()) |
| 516 return nullptr; |
511 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); | 517 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelera
tion); |
512 if (snapshot) { | 518 if (snapshot) { |
513 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); | 519 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8
888_SkColorType, kUnpremul_SkAlphaType); |
514 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); | 520 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo
.minRowBytes(), 0, 0); |
515 } | 521 } |
516 return imageData; | 522 return imageData; |
517 } | 523 } |
518 | 524 |
519 imageData = ImageData::create(m_size); | 525 imageData = ImageData::create(m_size, exceptionState); |
| 526 if (exceptionState.hadException()) |
| 527 return nullptr; |
520 | 528 |
521 if (!m_context) | 529 if (!m_context) |
522 return imageData; | 530 return imageData; |
523 | 531 |
524 ASSERT(m_context->is2d()); | 532 ASSERT(m_context->is2d()); |
525 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); | 533 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAcceleration
); |
526 if (snapshot) { | 534 if (snapshot) { |
527 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); | 535 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_
SkColorType, kUnpremul_SkAlphaType); |
528 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); | 536 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min
RowBytes(), 0, 0); |
529 } | 537 } |
530 | 538 |
531 return imageData; | 539 return imageData; |
532 } | 540 } |
533 | 541 |
534 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer) const | 542 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double
& quality, SourceDrawingBuffer sourceBuffer, ExceptionState& exceptionState) con
st |
535 { | 543 { |
536 if (!isPaintable()) | 544 if (!isPaintable()) |
537 return String("data:,"); | 545 return String("data:,"); |
538 | 546 |
539 String encodingMimeType = toEncodingMimeType(mimeType); | 547 String encodingMimeType = toEncodingMimeType(mimeType); |
540 | 548 |
541 ImageData* imageData = toImageData(sourceBuffer); | 549 ImageData* imageData = toImageData(sourceBuffer, exceptionState); |
| 550 if (exceptionState.hadException()) |
| 551 return String(); |
| 552 |
542 ScopedDisposal<ImageData> disposer(imageData); | 553 ScopedDisposal<ImageData> disposer(imageData); |
543 | 554 |
544 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); | 555 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU
RL(encodingMimeType, quality); |
545 } | 556 } |
546 | 557 |
547 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const | 558 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q
ualityArgument, ExceptionState& exceptionState) const |
548 { | 559 { |
549 if (!originClean()) { | 560 if (!originClean()) { |
550 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); | 561 exceptionState.throwSecurityError("Tainted canvases may not be exported.
"); |
551 return String(); | 562 return String(); |
552 } | 563 } |
553 double quality = UndefinedQualityValue; | 564 double quality = UndefinedQualityValue; |
554 if (!qualityArgument.isEmpty()) { | 565 if (!qualityArgument.isEmpty()) { |
555 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 566 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
556 if (v8Value->IsNumber()) { | 567 if (v8Value->IsNumber()) { |
557 quality = v8Value.As<v8::Number>()->Value(); | 568 quality = v8Value.As<v8::Number>()->Value(); |
558 } | 569 } |
559 } | 570 } |
560 return toDataURLInternal(mimeType, quality, BackBuffer); | 571 return toDataURLInternal(mimeType, quality, BackBuffer, exceptionState); |
561 } | 572 } |
562 | 573 |
563 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz
e imageSize, FileCallback* callback, const String& mimeType, double quality) | 574 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz
e imageSize, FileCallback* callback, const String& mimeType, double quality) |
564 { | 575 { |
565 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); | 576 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); |
566 | 577 |
567 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua
lity, encodedImage.get())) { | 578 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua
lity, encodedImage.get())) { |
568 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin
d(&FileCallback::handleEvent, callback, nullptr)); | 579 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin
d(&FileCallback::handleEvent, callback, nullptr)); |
569 } else { | 580 } else { |
570 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr
eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT
ype, AllowCrossThreadAccess(callback))); | 581 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr
eadSafeBind(&HTMLCanvasElement::createBlobAndCall, encodedImage.release(), mimeT
ype, AllowCrossThreadAccess(callback))); |
(...skipping 25 matching lines...) Expand all Loading... |
596 double quality = UndefinedQualityValue; | 607 double quality = UndefinedQualityValue; |
597 if (!qualityArgument.isEmpty()) { | 608 if (!qualityArgument.isEmpty()) { |
598 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 609 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
599 if (v8Value->IsNumber()) { | 610 if (v8Value->IsNumber()) { |
600 quality = v8Value.As<v8::Number>()->Value(); | 611 quality = v8Value.As<v8::Number>()->Value(); |
601 } | 612 } |
602 } | 613 } |
603 | 614 |
604 String encodingMimeType = toEncodingMimeType(mimeType); | 615 String encodingMimeType = toEncodingMimeType(mimeType); |
605 | 616 |
606 ImageData* imageData = toImageData(BackBuffer); | 617 ImageData* imageData = toImageData(BackBuffer, exceptionState); |
607 // imageData unref its data, which we still keep alive for the async toBlob
thread | 618 if (exceptionState.hadException()) |
| 619 return; |
| 620 |
| 621 // ImageData unrefs its data, which we still keep alive for the async toBlob
thread |
608 ScopedDisposal<ImageData> disposer(imageData); | 622 ScopedDisposal<ImageData> disposer(imageData); |
609 | 623 |
610 // Add a ref to keep image data alive until completion of encoding | 624 // Add a ref to keep image data alive until completion of encoding |
611 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); | 625 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
612 | 626 |
613 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread
SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR
ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en
codingMimeType, quality))); | 627 getToBlobThreadInstance()->taskRunner()->postTask(FROM_HERE, new Task(thread
SafeBind(&HTMLCanvasElement::encodeImageAsync, AllowCrossThreadAccess(imageDataR
ef.release().leakRef()), imageData->size(), AllowCrossThreadAccess(callback), en
codingMimeType, quality))); |
614 } | 628 } |
615 | 629 |
616 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 630 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
617 { | 631 { |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 { | 993 { |
980 return FloatSize(width(), height()); | 994 return FloatSize(width(), height()); |
981 } | 995 } |
982 | 996 |
983 bool HTMLCanvasElement::isOpaque() const | 997 bool HTMLCanvasElement::isOpaque() const |
984 { | 998 { |
985 return m_context && !m_context->hasAlpha(); | 999 return m_context && !m_context->hasAlpha(); |
986 } | 1000 } |
987 | 1001 |
988 } // blink | 1002 } // blink |
OLD | NEW |