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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 2361493003: Make toDataURL robust with respect to allocation failures (Closed)
Patch Set: drive-by fix for toBlob Created 4 years, 2 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) 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 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 { 618 {
619 ImageData* imageData; 619 ImageData* imageData;
620 if (is3D()) { 620 if (is3D()) {
621 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL(). 621 // Get non-premultiplied data because of inaccurate premultiplied alpha conversion of buffer()->toDataURL().
622 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer); 622 imageData = m_context->paintRenderingResultsToImageData(sourceBuffer);
623 if (imageData) 623 if (imageData)
624 return imageData; 624 return imageData;
625 625
626 m_context->paintRenderingResultsToCanvas(sourceBuffer); 626 m_context->paintRenderingResultsToCanvas(sourceBuffer);
627 imageData = ImageData::create(m_size); 627 imageData = ImageData::create(m_size);
628 if (hasImageBuffer()) { 628 if (imageData && hasImageBuffer()) {
629 sk_sp<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccel eration, reason); 629 sk_sp<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccel eration, reason);
630 if (snapshot) { 630 if (snapshot) {
631 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRG BA_8888_SkColorType, kUnpremul_SkAlphaType); 631 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRG BA_8888_SkColorType, kUnpremul_SkAlphaType);
632 snapshot->readPixels(imageInfo, imageData->data()->data(), image Info.minRowBytes(), 0, 0); 632 snapshot->readPixels(imageInfo, imageData->data()->data(), image Info.minRowBytes(), 0, 0);
633 } 633 }
634 } 634 }
635 return imageData; 635 return imageData;
636 } 636 }
637 637
638 imageData = ImageData::create(m_size); 638 imageData = ImageData::create(m_size);
639 639
640 if (!m_context) 640 if (!m_context || !imageData)
641 return imageData; 641 return imageData;
642 642
643 DCHECK(m_context->is2d()); 643 DCHECK(m_context->is2d());
644 if (hasImageBuffer()) { 644 if (hasImageBuffer()) {
645 sk_sp<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelerat ion, reason); 645 sk_sp<SkImage> snapshot = buffer()->newSkImageSnapshot(PreferNoAccelerat ion, reason);
646 if (snapshot) { 646 if (snapshot) {
647 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8 888_SkColorType, kUnpremul_SkAlphaType); 647 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8 888_SkColorType, kUnpremul_SkAlphaType);
648 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo .minRowBytes(), 0, 0); 648 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo .minRowBytes(), 0, 0);
649 } 649 }
650 } 650 }
651 651
652 return imageData; 652 return imageData;
653 } 653 }
654 654
655 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double & quality, SourceDrawingBuffer sourceBuffer) const 655 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double & quality, SourceDrawingBuffer sourceBuffer) const
656 { 656 {
657 if (!isPaintable()) 657 if (!isPaintable())
658 return String("data:,"); 658 return String("data:,");
659 659
660 String encodingMimeType = toEncodingMimeType(mimeType, EncodeReasonToDataURL ); 660 String encodingMimeType = toEncodingMimeType(mimeType, EncodeReasonToDataURL );
661 661
662 ImageData* imageData = toImageData(sourceBuffer, SnapshotReasonToDataURL); 662 ImageData* imageData = toImageData(sourceBuffer, SnapshotReasonToDataURL);
663 663
664 if (!imageData) // allocation failure
665 return String("data:,");
666
664 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); 667 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality);
665 } 668 }
666 669
667 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const 670 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const
668 { 671 {
669 if (surfaceLayerBridge()) { 672 if (surfaceLayerBridge()) {
670 exceptionState.throwDOMException(InvalidStateError, "canvas.toDataURL is not allowed for a canvas that has transferred its control to offscreen."); 673 exceptionState.throwDOMException(InvalidStateError, "canvas.toDataURL is not allowed for a canvas that has transferred its control to offscreen.");
671 return String(); 674 return String();
672 } 675 }
673 if (!originClean()) { 676 if (!originClean()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); 741 v8::Local<v8::Value> v8Value = qualityArgument.v8Value();
739 if (v8Value->IsNumber()) { 742 if (v8Value->IsNumber()) {
740 quality = v8Value.As<v8::Number>()->Value(); 743 quality = v8Value.As<v8::Number>()->Value();
741 } 744 }
742 } 745 }
743 746
744 String encodingMimeType = toEncodingMimeType(mimeType, EncodeReasonToBlobCal lback); 747 String encodingMimeType = toEncodingMimeType(mimeType, EncodeReasonToBlobCal lback);
745 748
746 ImageData* imageData = toImageData(BackBuffer, SnapshotReasonToBlob); 749 ImageData* imageData = toImageData(BackBuffer, SnapshotReasonToBlob);
747 750
751 if (!imageData) {
752 // ImageData allocation faillure
753 TaskRunnerHelper::get(TaskType::CanvasBlobSerialization, &document())->p ostTask(BLINK_FROM_HERE, WTF::bind(&BlobCallback::handleEvent, wrapPersistent(ca llback), nullptr));
754 return;
755 }
756
748 CanvasAsyncBlobCreator* asyncCreator = CanvasAsyncBlobCreator::create(imageD ata->data(), encodingMimeType, imageData->size(), callback, startTime, document( )); 757 CanvasAsyncBlobCreator* asyncCreator = CanvasAsyncBlobCreator::create(imageD ata->data(), encodingMimeType, imageData->size(), callback, startTime, document( ));
749 758
750 bool useIdlePeriodScheduling = (encodingMimeType != "image/webp"); 759 bool useIdlePeriodScheduling = (encodingMimeType != "image/webp");
751 asyncCreator->scheduleAsyncBlobCreation(useIdlePeriodScheduling, quality); 760 asyncCreator->scheduleAsyncBlobCreation(useIdlePeriodScheduling, quality);
752 } 761 }
753 762
754 void HTMLCanvasElement::addListener(CanvasDrawListener* listener) 763 void HTMLCanvasElement::addListener(CanvasDrawListener* listener)
755 { 764 {
756 m_listeners.add(listener); 765 m_listeners.add(listener);
757 } 766 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 1296
1288 bool HTMLCanvasElement::createSurfaceLayer() 1297 bool HTMLCanvasElement::createSurfaceLayer()
1289 { 1298 {
1290 DCHECK(!m_surfaceLayerBridge); 1299 DCHECK(!m_surfaceLayerBridge);
1291 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne w CanvasSurfaceLayerBridgeClientImpl()); 1300 std::unique_ptr<CanvasSurfaceLayerBridgeClient> bridgeClient = wrapUnique(ne w CanvasSurfaceLayerBridgeClientImpl());
1292 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri dgeClient))); 1301 m_surfaceLayerBridge = wrapUnique(new CanvasSurfaceLayerBridge(std::move(bri dgeClient)));
1293 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height( )); 1302 return m_surfaceLayerBridge->createSurfaceLayer(this->width(), this->height( ));
1294 } 1303 }
1295 1304
1296 } // namespace blink 1305 } // 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