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 28 matching lines...) Expand all Loading... | |
39 #include "core/frame/Settings.h" | 39 #include "core/frame/Settings.h" |
40 #include "core/html/ImageData.h" | 40 #include "core/html/ImageData.h" |
41 #include "core/html/canvas/CanvasContextCreationAttributes.h" | 41 #include "core/html/canvas/CanvasContextCreationAttributes.h" |
42 #include "core/html/canvas/CanvasFontCache.h" | 42 #include "core/html/canvas/CanvasFontCache.h" |
43 #include "core/html/canvas/CanvasRenderingContext.h" | 43 #include "core/html/canvas/CanvasRenderingContext.h" |
44 #include "core/html/canvas/CanvasRenderingContextFactory.h" | 44 #include "core/html/canvas/CanvasRenderingContextFactory.h" |
45 #include "core/layout/LayoutHTMLCanvas.h" | 45 #include "core/layout/LayoutHTMLCanvas.h" |
46 #include "core/paint/DeprecatedPaintLayer.h" | 46 #include "core/paint/DeprecatedPaintLayer.h" |
47 #include "platform/MIMETypeRegistry.h" | 47 #include "platform/MIMETypeRegistry.h" |
48 #include "platform/RuntimeEnabledFeatures.h" | 48 #include "platform/RuntimeEnabledFeatures.h" |
49 #include "platform/Task.h" | |
50 #include "platform/ThreadSafeFunctional.h" | |
49 #include "platform/graphics/Canvas2DImageBufferSurface.h" | 51 #include "platform/graphics/Canvas2DImageBufferSurface.h" |
50 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" | 52 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" |
51 #include "platform/graphics/ImageBuffer.h" | 53 #include "platform/graphics/ImageBuffer.h" |
52 #include "platform/graphics/RecordingImageBufferSurface.h" | 54 #include "platform/graphics/RecordingImageBufferSurface.h" |
53 #include "platform/graphics/StaticBitmapImage.h" | 55 #include "platform/graphics/StaticBitmapImage.h" |
54 #include "platform/graphics/UnacceleratedImageBufferSurface.h" | 56 #include "platform/graphics/UnacceleratedImageBufferSurface.h" |
55 #include "platform/graphics/gpu/AcceleratedImageBufferSurface.h" | 57 #include "platform/graphics/gpu/AcceleratedImageBufferSurface.h" |
56 #include "platform/transforms/AffineTransform.h" | 58 #include "platform/transforms/AffineTransform.h" |
57 #include "public/platform/Platform.h" | 59 #include "public/platform/Platform.h" |
58 #include "public/platform/WebTraceLocation.h" | 60 #include "public/platform/WebTraceLocation.h" |
59 #include "wtf/Functional.h" | |
60 #include <math.h> | 61 #include <math.h> |
61 #include <v8.h> | 62 #include <v8.h> |
62 | 63 |
63 namespace blink { | 64 namespace blink { |
64 | 65 |
65 using namespace HTMLNames; | 66 using namespace HTMLNames; |
66 | 67 |
67 namespace { | 68 namespace { |
68 | 69 |
69 // These values come from the WhatWG spec. | 70 // These values come from the WhatWG spec. |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 ASSERT(m_context->is2d()); | 504 ASSERT(m_context->is2d()); |
504 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(); | 505 RefPtr<SkImage> snapshot = buffer()->newSkImageSnapshot(); |
505 if (snapshot) { | 506 if (snapshot) { |
506 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_ SkColorType, kUnpremul_SkAlphaType); | 507 SkImageInfo imageInfo = SkImageInfo::Make(width(), height(), kRGBA_8888_ SkColorType, kUnpremul_SkAlphaType); |
507 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min RowBytes(), 0, 0); | 508 snapshot->readPixels(imageInfo, imageData->data()->data(), imageInfo.min RowBytes(), 0, 0); |
508 } | 509 } |
509 | 510 |
510 return imageData; | 511 return imageData; |
511 } | 512 } |
512 | 513 |
513 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double * quality, SourceDrawingBuffer sourceBuffer) const | 514 String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double & quality, SourceDrawingBuffer sourceBuffer) const |
514 { | 515 { |
515 if (!isPaintable()) | 516 if (!isPaintable()) |
516 return String("data:,"); | 517 return String("data:,"); |
517 | 518 |
518 String encodingMimeType = toEncodingMimeType(mimeType); | 519 String encodingMimeType = toEncodingMimeType(mimeType); |
519 | 520 |
520 ImageData* imageData = toImageData(sourceBuffer); | 521 ImageData* imageData = toImageData(sourceBuffer); |
521 ScopedDisposal<ImageData> disposer(imageData); | 522 ScopedDisposal<ImageData> disposer(imageData); |
522 | 523 |
523 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); | 524 return ImageDataBuffer(imageData->size(), imageData->data()->data()).toDataU RL(encodingMimeType, quality); |
524 } | 525 } |
525 | 526 |
526 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const | 527 String HTMLCanvasElement::toDataURL(const String& mimeType, const ScriptValue& q ualityArgument, ExceptionState& exceptionState) const |
527 { | 528 { |
528 if (!originClean()) { | 529 if (!originClean()) { |
529 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 530 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
530 return String(); | 531 return String(); |
531 } | 532 } |
532 double quality; | 533 double quality = -1.0; |
Justin Novosad
2015/09/21 14:12:38
Use a named constant instead of a literal here. Th
| |
533 double* qualityPtr = nullptr; | |
534 if (!qualityArgument.isEmpty()) { | 534 if (!qualityArgument.isEmpty()) { |
535 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 535 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
536 if (v8Value->IsNumber()) { | 536 if (v8Value->IsNumber()) { |
537 quality = v8Value.As<v8::Number>()->Value(); | 537 quality = v8Value.As<v8::Number>()->Value(); |
538 qualityPtr = &quality; | |
539 } | 538 } |
540 } | 539 } |
541 return toDataURLInternal(mimeType, qualityPtr, BackBuffer); | 540 return toDataURLInternal(mimeType, quality, BackBuffer); |
542 } | 541 } |
543 | 542 |
544 void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, c onst ScriptValue& qualityArgument, ExceptionState& exceptionState) const | 543 void HTMLCanvasElement::encodeImageAsync(DOMUint8ClampedArray* imageData, IntSiz e imageSize, FileCallback* callback, const String& mimeType, double quality) |
544 { | |
545 // Create an OwnPtr for this worker thread to hold the encoded image vector | |
Justin Novosad
2015/09/21 14:12:38
"worker" is a loaded word, don't use it here. Also
| |
546 OwnPtr<Vector<char>> encodedImage(adoptPtr(new Vector<char>())); | |
547 | |
548 // Perform image encoding | |
Justin Novosad
2015/09/21 14:12:38
Useless comment
| |
549 if (!ImageDataBuffer(imageSize, imageData->data()).encodeImage(mimeType, qua lity, encodedImage.get())) { | |
550 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin d(&FileCallback::handleEvent, callback, nullptr)); | |
551 } else { | |
552 // Pass the pointer of encoded image vector to the main thread | |
Justin Novosad
2015/09/21 14:12:38
Useless comment.
| |
553 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, thr eadSafeBind(&HTMLCanvasElement::createBlobAndCall, AllowCrossThreadAccess(this), encodedImage.release(), mimeType, AllowCrossThreadAccess(callback))); | |
554 } | |
555 } | |
556 | |
557 void HTMLCanvasElement::createBlobAndCall(PassOwnPtr<Vector<char>> encodedImage, const String& mimeType, FileCallback* callback) | |
558 { | |
559 // The main thread takes ownership of encoded image vector | |
560 OwnPtr<Vector<char>> enc(encodedImage); | |
561 | |
562 File* resultBlob = File::create(enc->data(), enc->size(), mimeType); | |
563 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bind(&F ileCallback::handleEvent, callback, resultBlob)); | |
564 } | |
565 | |
566 void HTMLCanvasElement::toBlob(FileCallback* callback, const String& mimeType, c onst ScriptValue& qualityArgument, ExceptionState& exceptionState) | |
545 { | 567 { |
546 if (!originClean()) { | 568 if (!originClean()) { |
547 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); | 569 exceptionState.throwSecurityError("Tainted canvases may not be exported. "); |
548 return; | 570 return; |
549 } | 571 } |
550 | 572 |
551 File* resultBlob = nullptr; | |
552 if (!isPaintable()) { | 573 if (!isPaintable()) { |
553 // If the canvas element's bitmap has no pixels | 574 // If the canvas element's bitmap has no pixels |
575 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bin d(&FileCallback::handleEvent, callback, nullptr)); | |
554 return; | 576 return; |
555 } | 577 } |
556 | 578 |
557 double quality; | 579 double quality = -1.0; |
Justin Novosad
2015/09/21 14:12:38
use a constant
| |
558 double* qualityPtr = nullptr; | |
559 if (!qualityArgument.isEmpty()) { | 580 if (!qualityArgument.isEmpty()) { |
560 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); | 581 v8::Local<v8::Value> v8Value = qualityArgument.v8Value(); |
561 if (v8Value->IsNumber()) { | 582 if (v8Value->IsNumber()) { |
562 quality = v8Value.As<v8::Number>()->Value(); | 583 quality = v8Value.As<v8::Number>()->Value(); |
563 qualityPtr = &quality; | |
564 } | 584 } |
565 } | 585 } |
566 | 586 |
567 String encodingMimeType = toEncodingMimeType(mimeType); | 587 String encodingMimeType = toEncodingMimeType(mimeType); |
568 | 588 |
569 ImageData* imageData = toImageData(BackBuffer); | 589 ImageData* imageData = toImageData(BackBuffer); |
590 // ImageData object will be disposed on leaving stack scope; only imageData- >data and imageData->size are passed to m_thread | |
570 ScopedDisposal<ImageData> disposer(imageData); | 591 ScopedDisposal<ImageData> disposer(imageData); |
571 | 592 |
572 // Perform image encoding | 593 // Add a ref to keep image data alive until completion of encoding |
573 Vector<char> encodedImage; | 594 RefPtr<DOMUint8ClampedArray> imageDataRef(imageData->data()); |
574 ImageDataBuffer(imageData->size(), imageData->data()->data()).encodeImage(en codingMimeType, qualityPtr, &encodedImage); | |
575 resultBlob = File::create(encodedImage.data(), encodedImage.size(), encoding MimeType); | |
576 | 595 |
577 Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, bind(&F ileCallback::handleEvent, callback, resultBlob)); | 596 if (!m_thread) { |
597 m_thread = adoptPtr(Platform::current()->createThread("Async toBlob")); | |
598 } | |
599 m_thread->taskRunner()->postTask(FROM_HERE, new Task(threadSafeBind(&HTMLCan vasElement::encodeImageAsync, AllowCrossThreadAccess(this), AllowCrossThreadAcce ss(imageDataRef.release().leakRef()), imageData->size(), AllowCrossThreadAccess( callback), encodingMimeType, quality))); | |
578 } | 600 } |
579 | 601 |
580 SecurityOrigin* HTMLCanvasElement::securityOrigin() const | 602 SecurityOrigin* HTMLCanvasElement::securityOrigin() const |
581 { | 603 { |
582 return document().securityOrigin(); | 604 return document().securityOrigin(); |
583 } | 605 } |
584 | 606 |
585 bool HTMLCanvasElement::originClean() const | 607 bool HTMLCanvasElement::originClean() const |
586 { | 608 { |
587 if (document().settings() && document().settings()->disableReadingFromCanvas ()) | 609 if (document().settings() && document().settings()->disableReadingFromCanvas ()) |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 { | 965 { |
944 return FloatSize(width(), height()); | 966 return FloatSize(width(), height()); |
945 } | 967 } |
946 | 968 |
947 bool HTMLCanvasElement::isOpaque() const | 969 bool HTMLCanvasElement::isOpaque() const |
948 { | 970 { |
949 return m_context && !m_context->hasAlpha(); | 971 return m_context && !m_context->hasAlpha(); |
950 } | 972 } |
951 | 973 |
952 } // blink | 974 } // blink |
OLD | NEW |