gfx/ycbcr/YCbCrUtils.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "gfx2DGlue.h"
     8 #include "YCbCrUtils.h"
     9 #include "yuv_convert.h"
    10 #include "ycbcr_to_rgb565.h"
    12 namespace mozilla {
    13 namespace gfx {
    15 void
    16 GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
    17                                SurfaceFormat& aSuggestedFormat,
    18                                IntSize& aSuggestedSize)
    19 {
    20   YUVType yuvtype =
    21     TypeFromSize(aData.mYSize.width,
    22                  aData.mYSize.height,
    23                  aData.mCbCrSize.width,
    24                  aData.mCbCrSize.height);
    26   // 'prescale' is true if the scaling is to be done as part of the
    27   // YCbCr to RGB conversion rather than on the RGB data when rendered.
    28   bool prescale = aSuggestedSize.width > 0 && aSuggestedSize.height > 0 &&
    29                   aSuggestedSize != aData.mPicSize;
    31   if (aSuggestedFormat == SurfaceFormat::R5G6B5) {
    32 #if defined(HAVE_YCBCR_TO_RGB565)
    33     if (prescale &&
    34         !IsScaleYCbCrToRGB565Fast(aData.mPicX,
    35                                   aData.mPicY,
    36                                   aData.mPicSize.width,
    37                                   aData.mPicSize.height,
    38                                   aSuggestedSize.width,
    39                                   aSuggestedSize.height,
    40                                   yuvtype,
    41                                   FILTER_BILINEAR) &&
    42         IsConvertYCbCrToRGB565Fast(aData.mPicX,
    43                                    aData.mPicY,
    44                                    aData.mPicSize.width,
    45                                    aData.mPicSize.height,
    46                                    yuvtype)) {
    47       prescale = false;
    48     }
    49 #else
    50     // yuv2rgb16 function not available
    51     aSuggestedFormat = SurfaceFormat::B8G8R8X8;
    52 #endif
    53   }
    54   else if (aSuggestedFormat != SurfaceFormat::B8G8R8X8) {
    55     // No other formats are currently supported.
    56     aSuggestedFormat = SurfaceFormat::B8G8R8X8;
    57   }
    58   if (aSuggestedFormat == SurfaceFormat::B8G8R8X8) {
    59     /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data.
    60      See bugs 639415 and 640073. */
    61     if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == YV24)
    62       prescale = false;
    63   }
    64   if (!prescale) {
    65     aSuggestedSize = aData.mPicSize;
    66   }
    67 }
    69 void
    70 ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
    71                   const SurfaceFormat& aDestFormat,
    72                   const IntSize& aDestSize,
    73                   unsigned char* aDestBuffer,
    74                   int32_t aStride)
    75 {
    76   // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
    77   // luma plane is odd sized.
    78   MOZ_ASSERT((aData.mCbCrSize.width == aData.mYSize.width ||
    79               aData.mCbCrSize.width == (aData.mYSize.width + 1) >> 1) &&
    80              (aData.mCbCrSize.height == aData.mYSize.height ||
    81               aData.mCbCrSize.height == (aData.mYSize.height + 1) >> 1));
    82   YUVType yuvtype =
    83     TypeFromSize(aData.mYSize.width,
    84                  aData.mYSize.height,
    85                  aData.mCbCrSize.width,
    86                  aData.mCbCrSize.height);
    88   // Convert from YCbCr to RGB now, scaling the image if needed.
    89   if (aDestSize != aData.mPicSize) {
    90 #if defined(HAVE_YCBCR_TO_RGB565)
    91     if (aDestFormat == SurfaceFormat::R5G6B5) {
    92       ScaleYCbCrToRGB565(aData.mYChannel,
    93                          aData.mCbChannel,
    94                          aData.mCrChannel,
    95                          aDestBuffer,
    96                          aData.mPicX,
    97                          aData.mPicY,
    98                          aData.mPicSize.width,
    99                          aData.mPicSize.height,
   100                          aDestSize.width,
   101                          aDestSize.height,
   102                          aData.mYStride,
   103                          aData.mCbCrStride,
   104                          aStride,
   105                          yuvtype,
   106                          FILTER_BILINEAR);
   107     } else
   108 #endif
   109       ScaleYCbCrToRGB32(aData.mYChannel, //
   110                         aData.mCbChannel,
   111                         aData.mCrChannel,
   112                         aDestBuffer,
   113                         aData.mPicSize.width,
   114                         aData.mPicSize.height,
   115                         aDestSize.width,
   116                         aDestSize.height,
   117                         aData.mYStride,
   118                         aData.mCbCrStride,
   119                         aStride,
   120                         yuvtype,
   121                         ROTATE_0,
   122                         FILTER_BILINEAR);
   123   } else { // no prescale
   124 #if defined(HAVE_YCBCR_TO_RGB565)
   125     if (aDestFormat == SurfaceFormat::R5G6B5) {
   126       ConvertYCbCrToRGB565(aData.mYChannel,
   127                            aData.mCbChannel,
   128                            aData.mCrChannel,
   129                            aDestBuffer,
   130                            aData.mPicX,
   131                            aData.mPicY,
   132                            aData.mPicSize.width,
   133                            aData.mPicSize.height,
   134                            aData.mYStride,
   135                            aData.mCbCrStride,
   136                            aStride,
   137                            yuvtype);
   138     } else // aDestFormat != gfxImageFormat::RGB16_565
   139 #endif
   140       ConvertYCbCrToRGB32(aData.mYChannel, //
   141                           aData.mCbChannel,
   142                           aData.mCrChannel,
   143                           aDestBuffer,
   144                           aData.mPicX,
   145                           aData.mPicY,
   146                           aData.mPicSize.width,
   147                           aData.mPicSize.height,
   148                           aData.mYStride,
   149                           aData.mCbCrStride,
   150                           aStride,
   151                           yuvtype);
   152   }
   153 }
   155 }
   156 }

mercurial