⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 176288 in webkit


Ignore:
Timestamp:
Nov 18, 2014, 2:54:52 PM (12 years ago)
Author:
timothy_horton@apple.com
Message:

Avoid re-encoding action menu image data
https://bugs.webkit.org/show_bug.cgi?id=138817
<rdar://problem/18840382>

Reviewed by Anders Carlsson.

  • Shared/mac/ActionMenuHitTestResult.h:
  • Shared/mac/ActionMenuHitTestResult.mm:

(WebKit::ActionMenuHitTestResult::encode):
(WebKit::ActionMenuHitTestResult::decode):
Store and encode a SharedMemory with the raw encoded image data,
instead of re-painting the image into a ShareableBitmap.

  • UIProcess/mac/WKActionMenuController.mm:

(-[WKActionMenuController _hitTestResultImage]):
(-[WKActionMenuController _defaultMenuItemsForImage]):
(-[WKActionMenuController _copyImage:]):
(-[WKActionMenuController _addImageToPhotos:]):
(-[WKActionMenuController _defaultMenuItems]):
(-[WKActionMenuController _canAddMediaToPhotos]): Deleted.
Build a temporary filename from a UUID and the image's desired extension.
Use the Image's encoded data instead of re-encoding it with CGImageDestination.
Build an image menu only if we have an image, URL, data, and extension.

  • WebProcess/WebPage/mac/WebPageMac.mm:

(WebKit::WebPage::performActionMenuHitTestAtLocation):

  • WebView/WebActionMenuController.mm:

(-[WebActionMenuController _defaultMenuItemsForImage:]):
(-[WebActionMenuController _addImageToPhotos:]):
Build a temporary filename from a UUID and the image's desired extension.
Use the Image's encoded data instead of re-encoding it with CGImageDestination.
Build an image menu only if we have an image, URL, data, and extension.

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/mac/ChangeLog

    r176265 r176288  
     12014-11-18  Tim Horton  <timothy_horton@apple.com>
     2
     3        Avoid re-encoding action menu image data
     4        https://bugs.webkit.org/show_bug.cgi?id=138817
     5        <rdar://problem/18840382>
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * WebView/WebActionMenuController.mm:
     10        (-[WebActionMenuController _defaultMenuItemsForImage:]):
     11        (-[WebActionMenuController _addImageToPhotos:]):
     12        Build a temporary filename from a UUID and the image's desired extension.
     13        Use the Image's encoded data instead of re-encoding it with CGImageDestination.
     14        Build an image menu only if we have an image, URL, data, and extension.
     15
    1162014-11-18  Daniel Bates  <dabates@apple.com>
    217
  • trunk/Source/WebKit/mac/WebView/WebActionMenuController.mm

    r176220 r176288  
    3939#import <ImageIO/ImageIO.h>
    4040#import <ImageKit/ImageKit.h>
     41#import <WebCore/ArchiveResource.h>
    4142#import <WebCore/DataDetection.h>
    4243#import <WebCore/DataDetectorsSPI.h>
    4344#import <WebCore/DictionaryLookup.h>
     45#import <WebCore/DocumentLoader.h>
    4446#import <WebCore/Editor.h>
    4547#import <WebCore/Element.h>
     
    5759#import <WebCore/RenderElement.h>
    5860#import <WebCore/RenderObject.h>
     61#import <WebCore/SharedBuffer.h>
    5962#import <WebCore/SoftLinking.h>
    6063#import <WebCore/TextCheckerClient.h>
     
    329332    RetainPtr<NSMenuItem> shareItem = [self _createActionMenuItemForTag:WebActionMenuItemTagShareImage];
    330333    if (Image* image = _hitTestResult.image()) {
    331         RetainPtr<CGImageRef> cgImage = image->getCGImageRef();
    332         RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithCGImage:cgImage.get() size:NSZeroSize]);
    333         _sharingServicePicker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ nsImage.get() ]]);
    334         [_sharingServicePicker setDelegate:self];
    335         [shareItem setSubmenu:[_sharingServicePicker menu]];
     334        RefPtr<SharedBuffer> buffer = image->data();
     335        if (buffer) {
     336            RetainPtr<NSData> nsData = [NSData dataWithBytes:buffer->data() length:buffer->size()];
     337            RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithData:nsData.get()]);
     338            _sharingServicePicker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ nsImage.get() ]]);
     339            [_sharingServicePicker setDelegate:self];
     340            [shareItem setSubmenu:[_sharingServicePicker menu]];
     341        } else
     342            [shareItem setEnabled:NO];
    336343    }
    337344
     
    405412        return;
    406413
    407     RetainPtr<CGImageRef> cgImage = image->getCGImageRef();
     414    String imageExtension = image->filenameExtension();
     415    if (imageExtension.isEmpty())
     416        return;
     417
     418    RefPtr<SharedBuffer> buffer = image->data();
     419    if (!buffer)
     420        return;
     421    RetainPtr<NSData> nsData = [NSData dataWithBytes:buffer->data() length:buffer->size()];
     422    RetainPtr<NSString> suggestedFilename = [[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:imageExtension];
    408423
    409424    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    410         NSString * const suggestedFilename = @"image.jpg";
    411 
    412         NSString *filePath = pathToPhotoOnDisk(suggestedFilename);
     425        NSString *filePath = pathToPhotoOnDisk(suggestedFilename.get());
    413426        if (!filePath)
    414427            return;
    415428
    416429        NSURL *fileURL = [NSURL fileURLWithPath:filePath];
    417         auto dest = adoptCF(CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeJPEG, 1, nullptr));
    418         CGImageDestinationAddImage(dest.get(), cgImage.get(), nullptr);
    419         CGImageDestinationFinalize(dest.get());
     430        [nsData writeToURL:fileURL atomically:NO];
    420431
    421432        dispatch_async(dispatch_get_main_queue(), ^{
     
    833844    }
    834845
    835     if (_hitTestResult.image() && !_hitTestResult.absoluteImageURL().isEmpty()) {
     846    Image* image = _hitTestResult.image();
     847    if (image && !_hitTestResult.absoluteImageURL().isEmpty() && !image->filenameExtension().isEmpty() && image->data() && !image->data()->isEmpty()) {
    836848        _type = WebActionMenuImage;
    837849        return [self _defaultMenuItemsForImage];
  • trunk/Source/WebKit2/ChangeLog

    r176283 r176288  
     12014-11-18  Tim Horton  <timothy_horton@apple.com>
     2
     3        Avoid re-encoding action menu image data
     4        https://bugs.webkit.org/show_bug.cgi?id=138817
     5        <rdar://problem/18840382>
     6
     7        Reviewed by Anders Carlsson.
     8
     9        * Shared/mac/ActionMenuHitTestResult.h:
     10        * Shared/mac/ActionMenuHitTestResult.mm:
     11        (WebKit::ActionMenuHitTestResult::encode):
     12        (WebKit::ActionMenuHitTestResult::decode):
     13        Store and encode a SharedMemory with the raw encoded image data,
     14        instead of re-painting the image into a ShareableBitmap.
     15
     16        * UIProcess/mac/WKActionMenuController.mm:
     17        (-[WKActionMenuController _hitTestResultImage]):
     18        (-[WKActionMenuController _defaultMenuItemsForImage]):
     19        (-[WKActionMenuController _copyImage:]):
     20        (-[WKActionMenuController _addImageToPhotos:]):
     21        (-[WKActionMenuController _defaultMenuItems]):
     22        (-[WKActionMenuController _canAddMediaToPhotos]): Deleted.
     23        Build a temporary filename from a UUID and the image's desired extension.
     24        Use the Image's encoded data instead of re-encoding it with CGImageDestination.
     25        Build an image menu only if we have an image, URL, data, and extension.
     26
     27        * WebProcess/WebPage/mac/WebPageMac.mm:
     28        (WebKit::WebPage::performActionMenuHitTestAtLocation):
     29
    1302014-11-18  Eric Carlson  <eric.carlson@apple.com>
    231
  • trunk/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.h

    r176221 r176288  
    2727#define ActionMenuHitTestResult_h
    2828
     29#include "DataReference.h"
    2930#include "ShareableBitmap.h"
     31#include "SharedMemory.h"
    3032#include "TextIndicator.h"
    3133#include "WebHitTestResult.h"
     
    5153
    5254    String lookupText;
    53     RefPtr<ShareableBitmap> image;
     55    RefPtr<SharedMemory> imageSharedMemory;
     56    String imageExtension;
    5457
    5558    RetainPtr<DDActionContext> actionContext;
  • trunk/Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm

    r176156 r176288  
    4343    encoder << hitTestResult;
    4444    encoder << lookupText;
     45    encoder << imageExtension;
    4546
    46     ShareableBitmap::Handle handle;
    47 
    48     // FIXME: We should consider sharing the raw original resource data so that metadata and whatnot are preserved.
    49     if (image)
    50         image->createHandle(handle, SharedMemory::ReadOnly);
    51 
    52     encoder << handle;
     47    SharedMemory::Handle imageHandle;
     48    if (imageSharedMemory && imageSharedMemory->size())
     49        imageSharedMemory->createHandle(imageHandle, SharedMemory::ReadOnly);
     50    encoder << imageHandle;
    5351
    5452    bool hasActionContext = actionContext;
     
    8381        return false;
    8482
    85     ShareableBitmap::Handle handle;
    86     if (!decoder.decode(handle))
     83    if (!decoder.decode(actionMenuHitTestResult.imageExtension))
    8784        return false;
    8885
    89     if (!handle.isNull())
    90         actionMenuHitTestResult.image = ShareableBitmap::create(handle, SharedMemory::ReadOnly);
     86    SharedMemory::Handle imageHandle;
     87    if (!decoder.decode(imageHandle))
     88        return false;
     89
     90    if (!imageHandle.isNull())
     91        actionMenuHitTestResult.imageSharedMemory = SharedMemory::create(imageHandle, SharedMemory::ReadOnly);
    9192
    9293    bool hasActionContext;
  • trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm

    r176238 r176288  
    459459#pragma mark Image actions
    460460
     461- (NSImage *)_hitTestResultImage
     462{
     463    RefPtr<SharedMemory> imageSharedMemory = _hitTestResult.imageSharedMemory;
     464    if (!imageSharedMemory)
     465        return nil;
     466
     467    RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithData:[NSData dataWithBytes:imageSharedMemory->data() length:imageSharedMemory->size()]]);
     468    return nsImage.autorelease();
     469}
     470
    461471- (NSArray *)_defaultMenuItemsForImage
    462472{
     
    470480    RetainPtr<NSMenuItem> shareItem = [self _createActionMenuItemForTag:kWKContextActionItemTagShareImage];
    471481
    472     if (RefPtr<ShareableBitmap> bitmap = _hitTestResult.image) {
    473         RetainPtr<CGImageRef> image = bitmap->makeCGImage();
    474         RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithCGImage:image.get() size:NSZeroSize]);
    475         _sharingServicePicker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ nsImage.get() ]]);
     482    if (RetainPtr<NSImage> image = [self _hitTestResultImage]) {
     483        _sharingServicePicker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ image.get() ]]);
    476484        [_sharingServicePicker setDelegate:self];
    477485        [shareItem setSubmenu:[_sharingServicePicker menu]];
     
    483491- (void)_copyImage:(id)sender
    484492{
    485     RefPtr<ShareableBitmap> bitmap = _hitTestResult.image;
    486     if (!bitmap)
    487         return;
    488 
    489     RetainPtr<CGImageRef> image = bitmap->makeCGImage();
    490     RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithCGImage:image.get() size:NSZeroSize]);
     493    RetainPtr<NSImage> image = [self _hitTestResultImage];
     494    if (!image)
     495        return;
     496
    491497    [[NSPasteboard generalPasteboard] clearContents];
    492     [[NSPasteboard generalPasteboard] writeObjects:@[ nsImage.get() ]];
     498    [[NSPasteboard generalPasteboard] writeObjects:@[ image.get() ]];
    493499}
    494500
     
    554560        return;
    555561
    556     RefPtr<ShareableBitmap> bitmap = _hitTestResult.image;
    557     if (!bitmap)
    558         return;
    559     RetainPtr<CGImageRef> image = bitmap->makeCGImage();
     562    RefPtr<SharedMemory> imageSharedMemory = _hitTestResult.imageSharedMemory;
     563    if (!imageSharedMemory->size() || _hitTestResult.imageExtension.isEmpty())
     564        return;
     565
     566    RetainPtr<NSData> imageData = adoptNS([[NSData alloc] initWithBytes:imageSharedMemory->data() length:imageSharedMemory->size()]);
     567    RetainPtr<NSString> suggestedFilename = [[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:_hitTestResult.imageExtension];
    560568
    561569    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    562         NSString * const suggestedFilename = @"image.jpg";
    563 
    564         NSString *filePath = pathToPhotoOnDisk(suggestedFilename);
     570        NSString *filePath = pathToPhotoOnDisk(suggestedFilename.get());
    565571        if (!filePath)
    566572            return;
    567573
    568574        NSURL *fileURL = [NSURL fileURLWithPath:filePath];
    569         auto dest = adoptCF(CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeJPEG, 1, nullptr));
    570         CGImageDestinationAddImage(dest.get(), image.get(), nullptr);
    571         CGImageDestinationFinalize(dest.get());
     575        [imageData writeToURL:fileURL atomically:NO];
    572576
    573577        dispatch_async(dispatch_get_main_queue(), ^{
     
    910914    }
    911915
    912     if (!hitTestResult->absoluteImageURL().isEmpty() && _hitTestResult.image) {
     916    if (!hitTestResult->absoluteImageURL().isEmpty() && _hitTestResult.imageSharedMemory && !_hitTestResult.imageExtension.isEmpty()) {
    913917        _type = kWKActionMenuImage;
    914918        return [self _defaultMenuItemsForImage];
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

    r176221 r176288  
    10101010
    10111011    if (Image* image = hitTestResult.image()) {
    1012         actionMenuResult.image = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha);
    1013         if (actionMenuResult.image)
    1014             actionMenuResult.image->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
     1012        RefPtr<SharedBuffer> buffer = image->data();
     1013        String imageExtension = image->filenameExtension();
     1014        if (!imageExtension.isEmpty() && buffer) {
     1015            actionMenuResult.imageSharedMemory = SharedMemory::create(buffer->size());
     1016            memcpy(actionMenuResult.imageSharedMemory->data(), buffer->data(), buffer->size());
     1017            actionMenuResult.imageExtension = imageExtension;
     1018        }
    10151019    }
    10161020
Note: See TracChangeset for help on using the changeset viewer.