LCOV - code coverage report
Current view: top level - gfx/layers - ImageDataSerializer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 17 111 15.3 %
Date: 2017-07-14 16:53:18 Functions: 5 17 29.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       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/. */
       5             : 
       6             : #include "ImageDataSerializer.h"
       7             : #include "gfx2DGlue.h"                  // for SurfaceFormatToImageFormat
       8             : #include "mozilla/gfx/Point.h"          // for IntSize
       9             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      10             : #include "mozilla/gfx/2D.h"             // for DataSourceSurface, Factory
      11             : #include "mozilla/gfx/Logging.h"        // for gfxDebug
      12             : #include "mozilla/gfx/Tools.h"          // for GetAlignedStride, etc
      13             : #include "mozilla/gfx/Types.h"
      14             : #include "mozilla/mozalloc.h"           // for operator delete, etc
      15             : #include "YCbCrUtils.h"                 // for YCbCr conversions
      16             : 
      17             : namespace mozilla {
      18             : namespace layers {
      19             : namespace ImageDataSerializer {
      20             : 
      21             : using namespace gfx;
      22             : 
      23             : int32_t
      24          27 : ComputeRGBStride(SurfaceFormat aFormat, int32_t aWidth)
      25             : {
      26          27 :   return GetAlignedStride<4>(aWidth, BytesPerPixel(aFormat));
      27             : }
      28             : 
      29             : int32_t
      30           9 : GetRGBStride(const RGBDescriptor& aDescriptor)
      31             : {
      32           9 :   return ComputeRGBStride(aDescriptor.format(), aDescriptor.size().width);
      33             : }
      34             : 
      35             : uint32_t
      36           9 : ComputeRGBBufferSize(IntSize aSize, SurfaceFormat aFormat)
      37             : {
      38           9 :   MOZ_ASSERT(aSize.height >= 0 && aSize.width >= 0);
      39             : 
      40             :   // This takes care of checking whether there could be overflow
      41             :   // with enough margin for the metadata.
      42           9 :   if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
      43           0 :     return 0;
      44             :   }
      45             : 
      46             :   // Note we're passing height instad of the bpp parameter, but the end
      47             :   // result is the same - and the bpp was already taken care of in the
      48             :   // ComputeRGBStride function.
      49           9 :   int32_t bufsize = GetAlignedStride<16>(ComputeRGBStride(aFormat, aSize.width),
      50           9 :                                          aSize.height);
      51             : 
      52           9 :   if (bufsize < 0) {
      53             :     // This should not be possible thanks to Factory::AllowedSurfaceSize
      54           0 :     return 0;
      55             :   }
      56             : 
      57           9 :   return bufsize;
      58             : }
      59             : 
      60             : 
      61             : 
      62             : // Minimum required shmem size in bytes
      63             : uint32_t
      64           0 : ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, int32_t aYStride,
      65             :                        const gfx::IntSize& aCbCrSize, int32_t aCbCrStride)
      66             : {
      67           0 :   MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
      68             : 
      69           0 :   if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0 ||
      70           0 :       !gfx::Factory::AllowedSurfaceSize(IntSize(aYStride, aYSize.height)) ||
      71           0 :       !gfx::Factory::AllowedSurfaceSize(IntSize(aCbCrStride, aCbCrSize.height))) {
      72           0 :     return 0;
      73             :   }
      74             :   // Overflow checks are performed in AllowedSurfaceSize
      75           0 :   return GetAlignedStride<4>(aYSize.height, aYStride) +
      76           0 :          2 * GetAlignedStride<4>(aCbCrSize.height, aCbCrStride);
      77             : }
      78             : 
      79             : // Minimum required shmem size in bytes
      80             : uint32_t
      81           0 : ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize)
      82             : {
      83           0 :   return ComputeYCbCrBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width);
      84             : }
      85             : 
      86             : uint32_t
      87           0 : ComputeYCbCrBufferSize(uint32_t aBufferSize)
      88             : {
      89           0 :   return GetAlignedStride<4>(aBufferSize, 1);
      90             : }
      91             : 
      92           0 : void ComputeYCbCrOffsets(int32_t yStride, int32_t yHeight,
      93             :                          int32_t cbCrStride, int32_t cbCrHeight,
      94             :                          uint32_t& outYOffset, uint32_t& outCbOffset,
      95             :                          uint32_t& outCrOffset)
      96             : {
      97           0 :   outYOffset = 0;
      98           0 :   outCbOffset = outYOffset + GetAlignedStride<4>(yStride, yHeight);
      99           0 :   outCrOffset = outCbOffset + GetAlignedStride<4>(cbCrStride, cbCrHeight);
     100           0 : }
     101             : 
     102          27 : gfx::SurfaceFormat FormatFromBufferDescriptor(const BufferDescriptor& aDescriptor)
     103             : {
     104          27 :   switch (aDescriptor.type()) {
     105             :     case BufferDescriptor::TRGBDescriptor:
     106          27 :       return aDescriptor.get_RGBDescriptor().format();
     107             :     case BufferDescriptor::TYCbCrDescriptor:
     108           0 :       return gfx::SurfaceFormat::YUV;
     109             :     default:
     110           0 :       MOZ_CRASH("GFX: FormatFromBufferDescriptor");
     111             :   }
     112             : }
     113             : 
     114           9 : gfx::IntSize SizeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
     115             : {
     116           9 :   switch (aDescriptor.type()) {
     117             :     case BufferDescriptor::TRGBDescriptor:
     118           9 :       return aDescriptor.get_RGBDescriptor().size();
     119             :     case BufferDescriptor::TYCbCrDescriptor:
     120           0 :       return aDescriptor.get_YCbCrDescriptor().ySize();
     121             :     default:
     122           0 :       MOZ_CRASH("GFX: SizeFromBufferDescriptor");
     123             :   }
     124             : }
     125             : 
     126           0 : Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
     127             : {
     128           0 :   switch (aDescriptor.type()) {
     129             :     case BufferDescriptor::TRGBDescriptor:
     130           0 :       return Nothing();
     131             :     case BufferDescriptor::TYCbCrDescriptor:
     132           0 :       return Some(aDescriptor.get_YCbCrDescriptor().cbCrSize());
     133             :     default:
     134           0 :       MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
     135             :   }
     136             : }
     137             : 
     138           0 : Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor)
     139             : {
     140             : {
     141           0 :   switch (aDescriptor.type()) {
     142             :     case BufferDescriptor::TRGBDescriptor:
     143           0 :       return Nothing();
     144             :     case BufferDescriptor::TYCbCrDescriptor:
     145           0 :       return Some(aDescriptor.get_YCbCrDescriptor().yUVColorSpace());
     146             :     default:
     147           0 :       MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
     148             :   }
     149             : }
     150             : }
     151             : 
     152           0 : Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
     153             : {
     154           0 :   switch (aDescriptor.type()) {
     155             :     case BufferDescriptor::TRGBDescriptor:
     156           0 :       return Nothing();
     157             :     case BufferDescriptor::TYCbCrDescriptor:
     158           0 :       return Some(aDescriptor.get_YCbCrDescriptor().stereoMode());
     159             :     default:
     160           0 :       MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
     161             :   }
     162             : }
     163             : 
     164           0 : uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor)
     165             : {
     166           0 :   return aBuffer + aDescriptor.yOffset();
     167             : }
     168             : 
     169           0 : uint8_t* GetCbChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor)
     170             : {
     171           0 :   return aBuffer + aDescriptor.cbOffset();
     172             : }
     173             : 
     174           0 : uint8_t* GetCrChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor)
     175             : {
     176           0 :   return aBuffer + aDescriptor.crOffset();
     177             : }
     178             : 
     179             : already_AddRefed<DataSourceSurface>
     180           0 : DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor, gfx::DataSourceSurface* aSurface)
     181             : {
     182           0 :   gfx::IntSize ySize = aDescriptor.ySize();
     183           0 :   gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
     184           0 :   int32_t yStride = ySize.width;
     185           0 :   int32_t cbCrStride = cbCrSize.width;
     186             : 
     187           0 :   RefPtr<DataSourceSurface> result;
     188           0 :   if (aSurface) {
     189           0 :     MOZ_ASSERT(aSurface->GetSize() == ySize);
     190           0 :     MOZ_ASSERT(aSurface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8);
     191           0 :     if (aSurface->GetSize() == ySize &&
     192           0 :         aSurface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8) {
     193           0 :       result = aSurface;
     194             :     }
     195             :   }
     196             : 
     197           0 :   if (!result) {
     198             :     result =
     199           0 :       Factory::CreateDataSourceSurface(ySize, gfx::SurfaceFormat::B8G8R8X8);
     200             :   }
     201           0 :   if (NS_WARN_IF(!result)) {
     202           0 :     return nullptr;
     203             :   }
     204             : 
     205             :   DataSourceSurface::MappedSurface map;
     206           0 :   if (NS_WARN_IF(!result->Map(DataSourceSurface::MapType::WRITE, &map))) {
     207           0 :     return nullptr;
     208             :   }
     209             : 
     210           0 :   layers::PlanarYCbCrData ycbcrData;
     211           0 :   ycbcrData.mYChannel     = GetYChannel(aBuffer, aDescriptor);
     212           0 :   ycbcrData.mYStride      = yStride;
     213           0 :   ycbcrData.mYSize        = ySize;
     214           0 :   ycbcrData.mCbChannel    = GetCbChannel(aBuffer, aDescriptor);
     215           0 :   ycbcrData.mCrChannel    = GetCrChannel(aBuffer, aDescriptor);
     216           0 :   ycbcrData.mCbCrStride   = cbCrStride;
     217           0 :   ycbcrData.mCbCrSize     = cbCrSize;
     218           0 :   ycbcrData.mPicSize      = ySize;
     219           0 :   ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
     220             : 
     221           0 :   gfx::ConvertYCbCrToRGB(ycbcrData,
     222             :                          gfx::SurfaceFormat::B8G8R8X8,
     223             :                          ySize,
     224             :                          map.mData,
     225           0 :                          map.mStride);
     226             : 
     227           0 :   result->Unmap();
     228           0 :   return result.forget();
     229             : }
     230             : 
     231             : void
     232           0 : ConvertAndScaleFromYCbCrDescriptor(uint8_t* aBuffer,
     233             :                                    const YCbCrDescriptor& aDescriptor,
     234             :                                    const gfx::SurfaceFormat& aDestFormat,
     235             :                                    const gfx::IntSize& aDestSize,
     236             :                                    unsigned char* aDestBuffer,
     237             :                                    int32_t aStride)
     238             : {
     239           0 :   MOZ_ASSERT(aBuffer);
     240           0 :   gfx::IntSize ySize = aDescriptor.ySize();
     241           0 :   gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
     242           0 :   int32_t yStride = ySize.width;
     243           0 :   int32_t cbCrStride = cbCrSize.width;
     244             : 
     245           0 :   layers::PlanarYCbCrData ycbcrData;
     246           0 :   ycbcrData.mYChannel     = GetYChannel(aBuffer, aDescriptor);
     247           0 :   ycbcrData.mYStride      = yStride;
     248           0 :   ycbcrData.mYSize        = ySize;
     249           0 :   ycbcrData.mCbChannel    = GetCbChannel(aBuffer, aDescriptor);
     250           0 :   ycbcrData.mCrChannel    = GetCrChannel(aBuffer, aDescriptor);
     251           0 :   ycbcrData.mCbCrStride   = cbCrStride;
     252           0 :   ycbcrData.mCbCrSize     = cbCrSize;
     253           0 :   ycbcrData.mPicSize      = ySize;
     254           0 :   ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
     255             : 
     256           0 :   gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
     257           0 : }
     258             : 
     259             : } // namespace ImageDataSerializer
     260             : } // namespace layers
     261             : } // namespace mozilla

Generated by: LCOV version 1.13