123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "gfx2DGlue.h"
- #include "YCbCrUtils.h"
- #include "yuv_convert.h"
- #include "ycbcr_to_rgb565.h"
- namespace mozilla {
- namespace gfx {
- void
- GetYCbCrToRGBDestFormatAndSize(const layers::PlanarYCbCrData& aData,
- SurfaceFormat& aSuggestedFormat,
- IntSize& aSuggestedSize)
- {
- YUVType yuvtype =
- TypeFromSize(aData.mYSize.width,
- aData.mYSize.height,
- aData.mCbCrSize.width,
- aData.mCbCrSize.height);
- // 'prescale' is true if the scaling is to be done as part of the
- // YCbCr to RGB conversion rather than on the RGB data when rendered.
- bool prescale = aSuggestedSize.width > 0 && aSuggestedSize.height > 0 &&
- aSuggestedSize != aData.mPicSize;
- if (aSuggestedFormat == SurfaceFormat::R5G6B5_UINT16) {
- #if defined(HAVE_YCBCR_TO_RGB565)
- if (prescale &&
- !IsScaleYCbCrToRGB565Fast(aData.mPicX,
- aData.mPicY,
- aData.mPicSize.width,
- aData.mPicSize.height,
- aSuggestedSize.width,
- aSuggestedSize.height,
- yuvtype,
- FILTER_BILINEAR) &&
- IsConvertYCbCrToRGB565Fast(aData.mPicX,
- aData.mPicY,
- aData.mPicSize.width,
- aData.mPicSize.height,
- yuvtype)) {
- prescale = false;
- }
- #else
- // yuv2rgb16 function not available
- aSuggestedFormat = SurfaceFormat::B8G8R8X8;
- #endif
- }
- else if (aSuggestedFormat != SurfaceFormat::B8G8R8X8) {
- // No other formats are currently supported.
- aSuggestedFormat = SurfaceFormat::B8G8R8X8;
- }
- if (aSuggestedFormat == SurfaceFormat::B8G8R8X8) {
- /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data.
- See bugs 639415 and 640073. */
- if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == YV24)
- prescale = false;
- }
- if (!prescale) {
- aSuggestedSize = aData.mPicSize;
- }
- }
- void
- ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
- const SurfaceFormat& aDestFormat,
- const IntSize& aDestSize,
- unsigned char* aDestBuffer,
- int32_t aStride)
- {
- // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
- // luma plane is odd sized.
- MOZ_ASSERT((aData.mCbCrSize.width == aData.mYSize.width ||
- aData.mCbCrSize.width == (aData.mYSize.width + 1) >> 1) &&
- (aData.mCbCrSize.height == aData.mYSize.height ||
- aData.mCbCrSize.height == (aData.mYSize.height + 1) >> 1));
- YUVType yuvtype =
- TypeFromSize(aData.mYSize.width,
- aData.mYSize.height,
- aData.mCbCrSize.width,
- aData.mCbCrSize.height);
- // Convert from YCbCr to RGB now, scaling the image if needed.
- if (aDestSize != aData.mPicSize) {
- #if defined(HAVE_YCBCR_TO_RGB565)
- if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
- ScaleYCbCrToRGB565(aData.mYChannel,
- aData.mCbChannel,
- aData.mCrChannel,
- aDestBuffer,
- aData.mPicX,
- aData.mPicY,
- aData.mPicSize.width,
- aData.mPicSize.height,
- aDestSize.width,
- aDestSize.height,
- aData.mYStride,
- aData.mCbCrStride,
- aStride,
- yuvtype,
- FILTER_BILINEAR);
- } else
- #endif
- ScaleYCbCrToRGB32(aData.mYChannel, //
- aData.mCbChannel,
- aData.mCrChannel,
- aDestBuffer,
- aData.mPicSize.width,
- aData.mPicSize.height,
- aDestSize.width,
- aDestSize.height,
- aData.mYStride,
- aData.mCbCrStride,
- aStride,
- yuvtype,
- aData.mYUVColorSpace,
- FILTER_BILINEAR);
- } else { // no prescale
- #if defined(HAVE_YCBCR_TO_RGB565)
- if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
- ConvertYCbCrToRGB565(aData.mYChannel,
- aData.mCbChannel,
- aData.mCrChannel,
- aDestBuffer,
- aData.mPicX,
- aData.mPicY,
- aData.mPicSize.width,
- aData.mPicSize.height,
- aData.mYStride,
- aData.mCbCrStride,
- aStride,
- yuvtype);
- } else // aDestFormat != SurfaceFormat::R5G6B5_UINT16
- #endif
- ConvertYCbCrToRGB32(aData.mYChannel, //
- aData.mCbChannel,
- aData.mCrChannel,
- aDestBuffer,
- aData.mPicX,
- aData.mPicY,
- aData.mPicSize.width,
- aData.mPicSize.height,
- aData.mYStride,
- aData.mCbCrStride,
- aStride,
- yuvtype,
- aData.mYUVColorSpace);
- }
- }
- } // namespace gfx
- } // namespace mozilla
|