tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

desktop_frame_cgimage.mm (4082B)


      1 /*
      2 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/desktop_capture/mac/desktop_frame_cgimage.h"
     12 
     13 #include <AvailabilityMacros.h>
     14 
     15 #include "rtc_base/checks.h"
     16 #include "rtc_base/logging.h"
     17 
     18 namespace webrtc {
     19 
     20 // static
     21 std::unique_ptr<DesktopFrameCGImage> DesktopFrameCGImage::CreateForDisplay(
     22    CGDirectDisplayID display_id) {
     23  // Create an image containing a snapshot of the display.
     24  webrtc::ScopedCFTypeRef<CGImageRef> cg_image(
     25      CGDisplayCreateImage(display_id));
     26  if (!cg_image) {
     27    return nullptr;
     28  }
     29 
     30  return DesktopFrameCGImage::CreateFromCGImage(cg_image);
     31 }
     32 
     33 // static
     34 std::unique_ptr<DesktopFrameCGImage> DesktopFrameCGImage::CreateForWindow(
     35    CGWindowID window_id) {
     36  webrtc::ScopedCFTypeRef<CGImageRef> cg_image(
     37      CGWindowListCreateImage(CGRectNull,
     38                              kCGWindowListOptionIncludingWindow,
     39                              window_id,
     40                              kCGWindowImageBoundsIgnoreFraming));
     41  if (!cg_image) {
     42    return nullptr;
     43  }
     44 
     45  return DesktopFrameCGImage::CreateFromCGImage(cg_image);
     46 }
     47 
     48 // static
     49 std::unique_ptr<DesktopFrameCGImage> DesktopFrameCGImage::CreateFromCGImage(
     50    webrtc::ScopedCFTypeRef<CGImageRef> cg_image) {
     51  // Verify that the image has 32-bit depth.
     52  int bits_per_pixel = CGImageGetBitsPerPixel(cg_image.get());
     53  if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) {
     54    RTC_LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with "
     55                      << bits_per_pixel
     56                      << " bits per pixel. Only 32-bit depth is supported.";
     57    return nullptr;
     58  }
     59 
     60  // Request access to the raw pixel data via the image's DataProvider.
     61  CGDataProviderRef cg_provider = CGImageGetDataProvider(cg_image.get());
     62  RTC_DCHECK(cg_provider);
     63 
     64  // CGDataProviderCopyData returns a new data object containing a copy of the
     65  // provider’s data.
     66  webrtc::ScopedCFTypeRef<CFDataRef> cg_data(
     67      CGDataProviderCopyData(cg_provider));
     68  RTC_DCHECK(cg_data);
     69 
     70  // CFDataGetBytePtr returns a read-only pointer to the bytes of a CFData
     71  // object.
     72  uint8_t* data = const_cast<uint8_t*>(CFDataGetBytePtr(cg_data.get()));
     73  RTC_DCHECK(data);
     74 
     75  DesktopSize size(CGImageGetWidth(cg_image.get()),
     76                   CGImageGetHeight(cg_image.get()));
     77  int stride = CGImageGetBytesPerRow(cg_image.get());
     78 
     79  std::unique_ptr<DesktopFrameCGImage> frame(
     80      new DesktopFrameCGImage(size, stride, data, cg_image, cg_data));
     81 
     82  CGColorSpaceRef cg_color_space = CGImageGetColorSpace(cg_image.get());
     83  if (cg_color_space) {
     84 #if !defined(MAC_OS_X_VERSION_10_13) || \
     85    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_13
     86    webrtc::ScopedCFTypeRef<CFDataRef> cf_icc_profile(
     87        CGColorSpaceCopyICCProfile(cg_color_space));
     88 #else
     89    webrtc::ScopedCFTypeRef<CFDataRef> cf_icc_profile(
     90        CGColorSpaceCopyICCData(cg_color_space));
     91 #endif
     92    if (cf_icc_profile) {
     93      const uint8_t* data_as_byte = reinterpret_cast<const uint8_t*>(
     94          CFDataGetBytePtr(cf_icc_profile.get()));
     95      const size_t data_size = CFDataGetLength(cf_icc_profile.get());
     96      if (data_as_byte && data_size > 0) {
     97        frame->set_icc_profile(
     98            std::vector<uint8_t>(data_as_byte, data_as_byte + data_size));
     99      }
    100    }
    101  }
    102 
    103  return frame;
    104 }
    105 
    106 DesktopFrameCGImage::DesktopFrameCGImage(
    107    DesktopSize size,
    108    int stride,
    109    uint8_t* data,
    110    webrtc::ScopedCFTypeRef<CGImageRef> cg_image,
    111    webrtc::ScopedCFTypeRef<CFDataRef> cg_data)
    112    : DesktopFrame(size, stride, data, nullptr),
    113      cg_image_(cg_image),
    114      cg_data_(cg_data) {
    115  RTC_DCHECK(cg_image_);
    116  RTC_DCHECK(cg_data_);
    117 }
    118 
    119 DesktopFrameCGImage::~DesktopFrameCGImage() = default;
    120 
    121 }  // namespace webrtc