X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=platform-abstractions%2Fportable%2Fimage-operations.h;h=b83cca12a03814173af828ee54926506c990b009;hb=6774f439cf1f339c40364110cb2eebd185bff000;hp=2d267255937f46e579971c59ae5741925c4ab87c;hpb=1b0107632bd508b5d5c3e6c5cdb54c76f456316d;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/platform-abstractions/portable/image-operations.h b/platform-abstractions/portable/image-operations.h index 2d26725..b83cca1 100644 --- a/platform-abstractions/portable/image-operations.h +++ b/platform-abstractions/portable/image-operations.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,20 @@ #ifndef DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_ #define DALI_INTERNAL_PLATFORM_IMAGE_OPERATIONS_H_ +// EXTERNAL INCLUDES +#include + // INTERNAL INCLUDES #include -#include +#include +#include + +#ifdef DALI_ADAPTOR_COMPILATION +#include +#else +#include +#endif -// EXTERNAL INCLUDES -#include namespace Dali { @@ -44,99 +52,21 @@ enum BoxDimensionTest }; /** - * @brief Simple class for passing around pairs of small ints. - * - * These are immutable. If you want to change a value, make a whole new object. - * @note One of these can be passed in a single 32 bit integer register on - * common architectures. - */ -class Vector2Uint16 -{ -public: - /** - * @brief Default constructor for the (0, 0) vector. - */ - Vector2Uint16() : mData(0) {} - - /** - * @brief Constructor taking separate x and y (width and height) parameters. - * @param[in] width The width or X dimension of the vector. Make sure it is less than 65536, - * @param[in] height The height or Y dimension of the vector. Make sure it is less than 65536, - */ - Vector2Uint16( uint32_t width, uint32_t height ) - { - DALI_ASSERT_DEBUG( width < ( 1u << 16 ) && "Width parameter not representable." ); - DALI_ASSERT_DEBUG( height < ( 1u << 16 ) && "Height parameter not representable." ); - - /* Do equivalent of the code below with one aligned memory access: - * mComponents[0] = width; - * mComponents[1] = height; - * Unit tests make sure this is equivalent. - **/ - mData = (height << 16u) + width; - } - - /** - * @brief Copy constructor. - */ - Vector2Uint16( const Vector2Uint16& rhs ) - { - mData = rhs.mData; - } - - /** - * @returns the x dimension stored in this 2-tuple. - */ - uint16_t GetWidth() const - { - return mComponents[0]; - } - - /** - * @returns the y dimension stored in this 2-tuple. - */ - uint16_t GetHeight() const - { - return mComponents[1]; - } - - /** - * @returns the x dimension stored in this 2-tuple. - */ - uint16_t GetX() const - { - return mComponents[0]; - } - - /** - * @returns the y dimension stored in this 2-tuple. - */ - uint16_t GetY() const - { - return mComponents[1]; - } - -private: - union - { - // Addressable view of X and Y: - uint16_t mComponents[2]; - // Packed view of X and Y to force alignment and allow a faster copy: - uint32_t mData; - }; -}; - -/** - * @brief Human readable text output. - */ -std::ostream& operator<<( std::ostream& o, const Vector2Uint16& vector ); - -/** * @brief The integer dimensions of an image or a region of an image packed into * 16 bits per component. * @note This can only be used for images of up to 65535 x 65535 pixels. */ -typedef Vector2Uint16 ImageDimensions; +typedef Uint16Pair ImageDimensions; + +/** + * @brief Work out the true desired width and height, accounting for special + * rules for zeros in either or both input requested dimensions. + * + * @param[in] rawDimensions Width and height of image before processing. + * @param[in] requestedDimensions Width and height of area to scale image into. Can be zero. + * @return Dimensions of area to scale image into after special rules are applied. + */ +ImageDimensions CalculateDesiredDimensions( ImageDimensions rawDimensions, ImageDimensions requestedDimensions ); /** * @defgroup BitmapOperations Bitmap-to-Bitmap Image operations. @@ -157,13 +87,16 @@ typedef Vector2Uint16 ImageDimensions; * bitmap passed-in, or the original bitmap passed in if the attributes * have no effect. */ -Integration::BitmapPtr ApplyAttributesToBitmap( Integration::BitmapPtr bitmap, const ImageAttributes& requestedAttributes ); +Dali::Devel::PixelBuffer ApplyAttributesToBitmap( Dali::Devel::PixelBuffer bitmap, ImageDimensions dimensions, FittingMode::Type fittingMode = FittingMode::DEFAULT, SamplingMode::Type samplingMode = SamplingMode::DEFAULT ); /** * @brief Apply downscaling to a bitmap according to requested attributes. * @note The input bitmap pixel buffer may be modified and used as scratch working space for efficiency, so it must be discarded. **/ -Integration::BitmapPtr DownscaleBitmap( Integration::Bitmap& bitmap, ImageDimensions desired, ImageAttributes::ScalingMode scalingMode, ImageAttributes::FilterMode filterMode ); +Dali::Devel::PixelBuffer DownscaleBitmap( Dali::Devel::PixelBuffer bitmap, + ImageDimensions desired, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode ); /**@}*/ /** @@ -192,8 +125,8 @@ void DownscaleInPlacePow2( unsigned char * const pixels, unsigned int inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, - ImageAttributes::ScalingMode scalingMode, - ImageAttributes::FilterMode filterMode, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, unsigned& outWidth, unsigned& outHeight ); @@ -338,6 +271,143 @@ void PointSample1BPP( const unsigned char * inPixels, unsigned int desiredWidth, unsigned int desiredHeight ); +/** + * @brief Resample input image to output image using a bilinear filter. + * + * Each output pixel is formed of a weighted sum of a 2x2 block of four input + * pixels + * @pre inPixels must not alias outPixels. The input image should be a totally + * separate buffer from the input one. + */ +void LinearSample( const unsigned char * __restrict__ inPixels, + ImageDimensions inDimensions, + Pixel::Format pixelFormat, + unsigned char * __restrict__ outPixels, + ImageDimensions outDimensions ); + +/** + * @copydoc LinearSample + * + * Specialised for one byte per pixel formats. + */ +void LinearSample1BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @copydoc LinearSample + * + * Specialised for two byte per pixel formats. + */ +void LinearSample2BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @copydoc LinearSample + * + * Specialised for RGB565 16 bit pixel format. + */ +void LinearSampleRGB565( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @copydoc LinearSample + * + * Specialised for three byte per pixel formats like RGB888. + */ +void LinearSample3BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @copydoc LinearSample + * + * Specialised for four byte per pixel formats like RGBA8888. + * @note, If used on RGBA8888, the A component will be blended independently. + */ +void LinearSample4BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @brief Resamples the input image with the Lanczos algorithm. + * + * @pre @p inPixels must not alias @p outPixels. The input image should be a totally + * separate buffer from the output buffer. + * + * @param[in] inPixels Pointer to the input image buffer. + * @param[in] inputDimensions The input dimensions of the image. + * @param[out] outPixels Pointer to the output image buffer. + * @param[in] desiredDimensions The output dimensions of the image. + */ +void LanczosSample4BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @brief Resamples the input image with the Lanczos algorithm. + * + * @pre @p inPixels must not alias @p outPixels. The input image should be a totally + * separate buffer from the output buffer. + * + * @param[in] inPixels Pointer to the input image buffer. + * @param[in] inputDimensions The input dimensions of the image. + * @param[out] outPixels Pointer to the output image buffer. + * @param[in] desiredDimensions The output dimensions of the image. + */ +void LanczosSample1BPP( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions ); + +/** + * @brief Resamples the input image with the Lanczos algorithm. + * + * @pre @p inPixels must not alias @p outPixels. The input image should be a totally + * separate buffer from the output buffer. + * + * @param[in] inPixels Pointer to the input image buffer. + * @param[in] inputDimensions The input dimensions of the image. + * @param[out] outPixels Pointer to the output image buffer. + * @param[in] desiredDimensions The output dimensions of the image. + */ +void Resample( const unsigned char * __restrict__ inPixels, + ImageDimensions inputDimensions, + unsigned char * __restrict__ outPixels, + ImageDimensions desiredDimensions, + Resampler::Filter filterType, + int numChannels, bool hasAlpha ); + + +/** + * @brief Rotates the input image with an implementation of the 'Rotate by Shear' algorithm. + * + * @param[in] pixelsIn The input buffer. + * @param[in] widthIn The width of the input buffer. + * @param[in] heightIn The height of the input buffer. + * @param[in] pixelSize The size of the pixel. + * @param[in] radians The rotation angle in radians. + * @param[out] pixelsOut The rotated output buffer. + * @param[out] widthOut The width of the output buffer. + * @param[out] heightOut The height of the output buffer. + */ +void RotateByShear( const uint8_t* const pixelsIn, + unsigned int widthIn, + unsigned int heightIn, + unsigned int pixelSize, + float radians, + uint8_t*& pixelsOut, + unsigned int& widthOut, + unsigned int& heightOut ); + /**@}*/ /** @@ -472,6 +542,42 @@ inline uint32_t AveragePixelRGB565( uint32_t a, uint32_t b ) return avg; } +/** @return The weighted blend of two integers as a 16.16 fixed-point number, given a 0.16 fixed-point blending factor. */ +inline unsigned int WeightedBlendIntToFixed1616(unsigned int a, unsigned int b, unsigned int fractBlend ) +{ + DALI_ASSERT_DEBUG( fractBlend <= 65535u && "Factor should be in 0.16 fixed-point." ); + const unsigned int weightedAFixed = a * (65535u - fractBlend); + const unsigned int weightedBFixed = b * fractBlend; + const unsigned blended = (weightedAFixed + weightedBFixed); + return blended; +} + +/** @brief Blend two 16.16 inputs to give a 16.32 output. */ +inline uint64_t WeightedBlendFixed1616ToFixed1632(unsigned int a, unsigned int b, unsigned int fractBlend ) +{ + DALI_ASSERT_DEBUG( fractBlend <= 65535u && "Factor should be in 0.16 fixed-point." ); + // Blend while promoting intermediates to 16.32 fixed point: + const uint64_t weightedAFixed = uint64_t(a) * (65535u - fractBlend); + const uint64_t weightedBFixed = uint64_t(b) * fractBlend; + const uint64_t blended = (weightedAFixed + weightedBFixed); + return blended; +} + +/** + * @brief Blend 4 taps into one value using horizontal and vertical weights. + */ +inline unsigned int BilinearFilter1Component(unsigned int tl, unsigned int tr, unsigned int bl, unsigned int br, unsigned int fractBlendHorizontal, unsigned int fractBlendVertical ) +{ + DALI_ASSERT_DEBUG( fractBlendHorizontal <= 65535u && "Factor should be in 0.16 fixed-point." ); + DALI_ASSERT_DEBUG( fractBlendVertical <= 65535u && "Factor should be in 0.16 fixed-point." ); + + const unsigned int topBlend = WeightedBlendIntToFixed1616( tl, tr, fractBlendHorizontal ); + const unsigned int botBlend = WeightedBlendIntToFixed1616( bl, br, fractBlendHorizontal ); + const uint64_t blended2x2 = WeightedBlendFixed1616ToFixed1632( topBlend, botBlend, fractBlendVertical ); + const unsigned int rounded = (blended2x2 + (1u << 31u) ) >> 32u; + return rounded; +} + /**@}*/ } /* namespace Platform */